여기

2010-11-18 4 views
2

이 놀라운 책 "리스프의 땅"에서 예를 들어, 일부 소스 코드입니다 여러 줄로 함수 속보 :여기

(defun random-node() 
    (1+ (random *node-num*))) 

(defun edge-pair (a b) 
    (unless (eql a b) 
    (list (cons a b) (cons b a)))) 

(defun make-edge-list() 
    (apply #'append (loop repeat *edge-num* 
          collect (edge-pair (random-node) (random-node))))) 

나는 리스프 본능을 가지고 있지 않기 때문에, 나는 그것을 찾을 메서드를 여러 줄로 (명령형으로) 분해 한 다음 함수형으로 변형하려고 할 때 유용합니다.

make-edge-list 기능을 여러 줄로 나눌 수있게 도와 주시겠습니까?

+0

최소한 표현식의 구성 요소를 let 표현식으로 바꾸는 것이 도움이 될 수 있습니다. 여기에서 사용하는 정확한 방언이 확실하지 않지만 적어도 더 자세한 설명 형식으로 분류 할 수 있어야합니다. '(let (pair (edge-pair (임의 노드) (랜덤 노드))) (...'등등. – Ashe

+0

뭔가 빠졌습니까? 처음 두 단계로 처리해야 할 이유가 있습니까? (루프 반복 * edge-num * append (edge-pair (임의 노드) (랜덤 - 놈)))?)'? – Ken

답변

1

Lisp에서는 라인이 의미가 없습니다. Lisp 표기법은 s- 표현식을 기반으로하며 텍스트 줄은 평가 중 Lisp에서 볼 수 없습니다. 공백에서 어떤 식 으로든 식을 분리 할 수 ​​있습니다.

(defun make-edge-list() 
    (apply #'append 
      (loop repeat *edge-num* 
                  collect (edge-pair (random-node) 
            (random-node))))) 

는이 같은 코드를 읽을 수 있습니다

  • 각 에지 쌍 conses의 목록입니다. 각 cons는 위치를 저장합니다.
  • 루프는 가장자리 쌍 목록을 반환합니다.
  • 그러면이 목록에 append가 적용되고 cons 목록이 반환됩니다. cons의 목록은 실제로 위치 목록입니다. 이 함수는 몇 가지 약간의 문제가 있음을

참고 :

  • 이 아닌 임의의 길이의 목록에 대한 작품을 적용합니다. 목록이 너무 길지 않기를 바랍니다.

  • 우리가 LOOP를 약간 변경하면 APPEND 기능의 적용이 실제로 필요하지 않습니다. LOOP는 COLLECT 일뿐만 아니라 APPEND도 할 수 있습니다.

+0

Arlen이 앞서 제안한 것과 같이 명령형으로 메소드를 나누고 싶습니다. – Chiron

+0

명령형으로 코드를 작성하려면 다른 프로그래밍 언어를 사용하는 것이 좋습니다. 함수가 거의 이해하지 못한다면 ... –

+0

"Lisp 본능이 없기 때문에 메서드를 여러 명령 줄 (명령형)으로 나누고 변형하려고하면 유용합니다. 기능적 스타일에. " – Chiron