LINUX.ORG.RU

HyperSpec loop macro

 


0

3

Меня интересует как это применять на практике, в умных книжках об этом ничего нет. Надеюсь что кто-нибудь знает.

HyperSpec

 loop [name-clause] {variable-clause}* {main-clause}* => result*

name-clause::= named name 

variable-clause::= with-clause | initial-final | for-as-clause 

with-clause::= with var1 [type-spec] [= form1] {and var2 [type-spec] [= form2]}* 

main-clause::= unconditional | accumulation | conditional | termination-test | initial-final 

initial-final::= initially compound-form+ | finally compound-form+ 

unconditional::= {do | doing} compound-form+ | return {form | it} 

accumulation::= list-accumulation | numeric-accumulation 

list-accumulation::= {collect | collecting | append | appending | nconc | nconcing} {form | it}  
                     [into simple-var] 

numeric-accumulation::= {count | counting | sum | summing | } 
                         maximize | maximizing | minimize | minimizing {form | it} 
                        [into simple-var] [type-spec] 

conditional::= {if | when | unless} form selectable-clause {and selectable-clause}*  
               [else selectable-clause {and selectable-clause}*]  
               [end] 

selectable-clause::= unconditional | accumulation | conditional 

termination-test::= while form | until form | repeat form | always form | never form | thereis form 

for-as-clause::= {for | as} for-as-subclause {and for-as-subclause}* 

for-as-subclause::= for-as-arithmetic | for-as-in-list | for-as-on-list | for-as-equals-then | 
                    for-as-across | for-as-hash | for-as-package 

for-as-arithmetic::= var [type-spec] for-as-arithmetic-subclause 

for-as-arithmetic-subclause::= arithmetic-up | arithmetic-downto | arithmetic-downfrom 

arithmetic-up::= [[{from | upfrom} form1 |   {to | upto | below} form2 |   by form3]]+ 

arithmetic-downto::= [[{{from form1}}1  |   {{{downto | above} form2}}1  |   by form3]] 

arithmetic-downfrom::= [[{{downfrom form1}}1  |   {to | downto | above} form2 |   by form3]] 

for-as-in-list::= var [type-spec] in form1 [by step-fun] 

for-as-on-list::= var [type-spec] on form1 [by step-fun] 

for-as-equals-then::= var [type-spec] = form1 [then form2] 

for-as-across::= var [type-spec] across vector 

for-as-hash::= var [type-spec] being {each | the}  
               {{hash-key | hash-keys} {in | of} hash-table  
                [using (hash-value other-var)] |  
                {hash-value | hash-values} {in | of} hash-table  
                [using (hash-key other-var)]} 

for-as-package::= var [type-spec] being {each | the}  
                  {symbol | symbols | 
                   present-symbol | present-symbols | 
                   external-symbol | external-symbols} 
                  [{in | of} package] 

type-spec::= simple-type-spec | destructured-type-spec 

simple-type-spec::= fixnum | float | t | nil 

destructured-type-spec::= of-type d-type-spec 

d-type-spec::= type-specifier | (d-type-spec . d-type-spec) 

var::= d-var-spec 

var1::= d-var-spec 

var2::= d-var-spec 

other-var::= d-var-spec 

d-var-spec::= simple-var | nil | (d-var-spec . d-var-spec) 

Ответ на: комментарий от no-such-file
На этих примерах явно не понятно как из рекурсии делать итерацию.

(loop
for item in list
for i from 1 to 10
do (something))

(loop for i upto 10 collect i)

(loop for i downto -10 collect i) ; wrong

is undefined. Instead, you need to write this:

(loop for i from 0 downto -10 collect i)

(loop for i in (list 10 20 30 40) collect i)

(loop for i in (list 10 20 30 40) by #'cddr collect i)

(loop for x on (list 10 20 30) collect x)

(loop for x on (list 10 20 30 40) by #'cddr collect x)

(loop for x across "abcd" collect x)

(loop for k being the hash-keys in h using (hash-value v) ...)
(loop for v being the hash-values in h using (hash-key k) ...)

(loop repeat 5
for x = 0 then y
for y = 1 then (+ x y)
collect y)

(loop for (a b) in '((1 2) (3 4) (5 6))
      do (format t "a: ~a; b: ~a~%" a b))

(loop for (item . rest) on list
do (format t "~a" item)
when rest do (format t ", "))

(loop for i in *random*
counting (evenp i) into evens
counting (oddp i) into odds
summing i into total
maximizing i into max
minimizing i into min
finally (return (list min max total evens odds)))

(loop for i from 1 to 10 do (print i))

(loop for i from 1 to 10 when (evenp i) sum i)

(loop named outer for list in lists do
(loop for item in list do
(if (what-i-am-looking-for-p item)
    (return-from outer item))))

(if (loop for n in numbers always (evenp n))
    (print "All numbers even."))

А здесь, прямое указание на метод научного тыка

The named clause, if any, must be the first clause.
After the named clause come all the initially, with, for, and repeat clauses.
Then comes the body clauses: conditional and unconditional execution,
accumulation, and termination test.
End with any finally clauses.

The LOOP macro will expand into code that performs the following actions:

• Initializes all local loop variables as declared with with or for clauses as well as those implicitly created by accumulation clauses. The initial value forms are evaluated in the order the clauses appear in the loop.

• Execute the forms provided by any initially clauses—the prologue—in the order they appear in the loop.

• Iterate, executing the body of the loop as described in the next paragraph.

• Execute the forms provided by any finally clauses—the epilogue—in the order they appear in the loop.

всё прочитал, как работать с HeperSpec нет ничего, не спасает, ещё есть идея как подойти к теме с которой начался этот тред.

saufesma ()
Ответ на: комментарий от anonymous

Полгода/год тому назад, казался вменяемым челом.

Имеется ввиду, чтобы стать вменяемым, надо превратиться в распространителя зарубежной литературы как [угодайка], так.

saufesma ()
Ответ на: комментарий от monk

Проблема стоит как делать из рекурсии итерацию. Книжка не описывает это явно, поэтому не понятно. Но если и ты предлагаешь почитать книжку, то это уже большая проблема.

saufesma ()
Ответ на: комментарий от saufesma

loop это не про то, как сделать итерацию из рекурссии. Это про то, как делать итерацию вообще. Если нужно из итерации сделать рекурсию, то надо думать вообще. Например, факториал можно описать рекурсивно так:

(defun fac-rec (n)
  (case n
    (0 1)
    (1 1)
    (t (* n (fac-rec (1- n))))))

Если же мы хотим сделать итерацию, то пишем так:

(defun fac-iter (n)                                                                                                                                                                             
  (loop with result = 1                                                                                                                                                                         
        for i from 1 to n                                                                                                                                                                       
        do (setf result (* result i))                                                                                                                                                           
        finally (return result)))

Так как я не нашёл возможность редуцировать через умножение, то просто объявил переменную result, значение которой меняю на каждом шаге. Ну как бы и всё.

turtle_bazon ★★★★★ ()
Ответ на: комментарий от monk

/Пытался вот такое переписать на loop, но это не актуально так как есть стандартные функции remove/delete

(defun list< (N L)
; Makes a copy of list L
; containing only elements
; that are < N.
; L must be a list of numbers.
(if (null L)
nil
(if (< (first L) N)
(cons (first L) (list< N (rest L)))
(list< N (rest L)))))

CL-USER> (list< 4 '(1 2 3 4 5))
(1 2 3)
CL-USER> (list< 0 '(1 2 3 4 5))
NIL
CL-USER> (list< 2 '(1 2 3 4 5))
(1 2 3 4)
CL-USER> (list< 2 '(1 2 3 4 5))
(1)
saufesma ()
Ответ на: комментарий от saufesma

Пытался вот такое переписать на loop

Казалось бы очевидно

(loop for i in '(1 2 3 4 5) when (< i 2) collect i)

Может тебе с чего-то попроще начать? Ну там, какие-то базовые вещи сначала освоить?

no-such-file ★★★★★ ()
Ответ на: комментарий от no-such-file

Ну там, какие-то базовые вещи сначала освоить?

Освоение базовых вещей не ведёт прямой дорогой к advanced, там что-то ещё надо, вот это и пытаюсь найти с вашей помощью.

saufesma ()