어떤 명령형 프로그래밍 언어가 재귀를 지원하지 않습니까?


21

내가 아는 한, 모든 현대적인 명령형 프로그래밍 언어는 프로 시저가 스스로 호출 할 수 있다는 의미에서 재귀를 지원합니다. 항상 그런 것은 아니지만 빠른 Google 검색으로 어려운 사실을 찾을 수는 없습니다. 그래서 내 질문은 :

처음부터 재귀를 지원하지 않는 언어는 무엇이며 언제 지원이 추가 되었습니까?

답변:


21

나는 COBOL이 확실하지는 않지만 (한 번에 확실하지는 않았지만) 아무도 돌보는 것을 상상할 수는 없습니다.

Fortran은 Fortran 90 이후부터 recursive키워드를 사용하여 서브 루틴이 재귀적임을 알려야합니다.

PL / I는 거의 동일했습니다. 재귀가 지원되었지만 어떤 절차가 재귀 적이 었는지 명시 적으로 알려 주어야했습니다.

그래도 그보다 더 많은 것이 있는지 의심합니다. 그것에 도달하면 재귀를 금지하는 것은 IBM (360/370/3090 / ...) 메인 프레임이 하드웨어 스택을 지원하지 않기 때문에 IBM이 언어 디자인에서 주로 한 일이었습니다. 대부분의 언어가 IBM에서 왔을 때 주로 재귀를 금지했습니다. 이제 모두 다른 곳에서 왔으므로 재귀가 항상 허용됩니다 (그러나 원래 Cray 1과 같은 다른 일부 컴퓨터에는 스택에 대한 하드웨어 지원도 없었습니다).


이 기간의 제어 데이터 컴퓨터는 재귀도 지원하지 않았습니다 (서브 루틴 호출은 호출 명령 + 1로 점프를 삽입하도록 코드를 수정 한 명령으로 수행되었습니다). Wirth는 6600에서 Pascal을 개발했을 때 아마도 서브 루틴을 호출하는 새로운 방법을 생각해 내야했습니다.
David Thornley

@David : 그렇습니다. 그리고 우연의 일치는 없습니다. 또한 Seymour Cray가 디자인했습니다. 한 번 Pascal 6000 컴파일러를 살펴 보았지만 스택 프레임을 생성 (시뮬레이션?)했는지 확인하지 않았습니다.
Jerry Coffin

notably the original cray 1공룡을 복제하기 위해 재귀가 필요하지 않습니까? 나는 원숭이가 나무를 통해 스윙하는 것은 정말로 우리에게 달려 있다고 생각합니다.
normanthesquid

2
CAML (및 OCAML, F #)조차도 명시 적으로 표시된 재귀 함수가 필요합니다.
jk.

1
@Panzercrisis : IBM이 x86에 관여했는지는 확실하지 않지만 현재 메인 프레임은 1964 년에 출시 된 IBM 360으로 직접 추적되므로 기본 설계는 x86보다 몇 십 년 정도 더 오래 전입니다.
Jerry Coffin

16

위키피디아의 말 :

Fortran과 같은 초기 언어는 반환 주소의 위치뿐만 아니라 변수가 정적으로 할당 되었기 때문에 처음에는 재귀를 지원하지 않았습니다.

http://en.wikipedia.org/wiki/Subroutine#Local_variables.2C_recursion_and_re-entrancy

FORTRAN 77은 재귀를 허용하지 않으며, Fortran 90은 재귀 루틴을 명시 적으로 선언해야합니다.

대부분의 FORTRAN 77 컴파일러는 재귀를 허용하지만 일부 (예 : DEC)는 컴파일러 옵션을 사용해야합니다 (컴파일러 옵션 장 참조). Fortran 77 표준을 엄격하게 준수하는 GNU g77은 재귀를 전혀 허용하지 않습니다.

http://www.ibiblio.org/pub/languages/fortran/ch1-12.html


iirc 최소한 하나의 FORTRAN 77 컴파일러가 있었는데, 기술적으로 재귀를 지원했지만 여러분이 가질 수있는 총 스택 프레임 수는 많은 문제에 효과적으로 사용할 수 없었습니다
jk.

6

OpenCL 프로그래밍 언어는 재귀를 지원하지 않습니다. ( OpenCL 사양 의 섹션 6.8 참조 )

이에 대한 현재의 동기는 a) 딥 스택을위한 공간 부족 b) 대규모 레지스터 세트와 광범위한 인라인이있는 경우 성능을 최적화하기 위해 필요한 총 할당량을 정적으로 알고 싶어한다는 것입니다.

이것은 다른 GPU 프로그래밍 언어, 예를 들어 쉐이더 언어에도 적용 할 수 있습니다.


2

소형 마이크로 컨트롤러 용 일부 c 컴파일러는 스택 크기가 매우 제한되어 있기 때문에 재귀를 지원하지 않습니다.


이러한 마이크로 컨트롤러 (예 : PIC16 제품군) 중 일부는 하드웨어 호출 스택 (명령으로 액세스 할 수 없음) 만 있고 다른 스택 형태는 없으므로 재귀를 사용할 때 함수는 로컬 변수를 가질 수 없었습니다 (데이터 스택이 명확하게 필요하기 때문에) 그것을 위해 ...) 참조 : en.wikipedia.org/wiki/PIC_microcontroller#Stacks
Ale

1

행 번호 시절의 BASIC은 재귀 지원이 좋지 않은 경향이있었습니다. 그 당시의 많은 (모든?) BASIC은 중첩 된 gosub 호출을 지원했지만 자체 호출에 유용한 방식으로 매개 변수 또는 값을 전달하는 쉬운 방법을 지원하지 않았습니다.

많은 초기 컴퓨터는 재귀에 문제가 있었는데, 일반적으로 (PDP8, IAS 시스템 계열, 아마도 익숙하지 않은 더 많은 아키텍처)라는 루틴의 시작 부분에 리턴 주소를 기록한 호출 명령을 사용했기 때문입니다. "루틴을 호출 한 후 명령으로 건너 뛰기"에 대한 기계어 코드입니다.


1

" 지원 "의 의미에 따라 다릅니다 . 재귀를 지원하려면 모든 재진입시 로컬 변수를 다시 인스턴스화 할 스택이 필요합니다.

언어에 로컬 변수 개념이없는 경우에도 "서브 루틴"개념이 있고 동일한 변수 (일명 배열) 사이의 인덱싱을 관리 할 수있는 방법이 있으면 입력 / 종료 할 때마다 글로벌 인덱스를 증가 / 감소시킬 수 있습니다 하나 이상의 배열 멤버를 통해 함수에 액세스합니다.

이것이 "지원"이라고 할 수 있는지 모르겠습니다. 사실은 COBOL과 마찬가지로 Fortran77에서했던 것처럼 ZX-Spectrum BASIC으로 재귀 함수를 작성했습니다 ... 항상 그 트릭으로.


1

어셈블리 언어 는 재귀를 직접 지원하지 않습니다. 일반적으로 기계 스택에 매개 변수를 밀어 넣어 "직접 수행"해야합니다.


2
메소드 호출을 지원하는 한 재귀를 지원합니다. 일반적으로 CALL서브 루틴으로 건너 뛰기 전에 IP를 스택으로 자동 푸시하는 RET명령어 와 리턴 주소를 IP로 팝 하는 명령어가 있습니다. CALL자신의 진입 점을 지킬 이유가 없습니다 .
Blorgbeard

@Blorgbeard-재귀 호출에 필요한 매개 변수를 처리하지 않으므로 일반적으로 이해되는 의미에서 "재귀를 지원합니다"로 계산하기에 충분하지 않다고 주장하지만 절대적으로 사실입니다.
mikera

1
재귀 호출에는 기술적으로 매개 변수가 필요하지 않습니다. void f() { f(); }재귀 적입니다.
Blorgbeard

엄밀히 말하면 그러나 한 가지 사소한 경우를 코딩 할 수 있다고해서 IMHO가 어셈블리를 "재귀 지원"으로 설명해야한다는 의미는 아닙니다. 대부분의 재귀 사용에는 매개 변수가 필요합니다.
mikera

당신이 그렇게 말할 수 있다고 생각합니다. 그러나이 경우 어셈블리도 루프를 지원하지 않습니다 (수동으로 CMP 및 JNZ를 사용해야 함). "지원"이라고 부르는 것이 문제라고 생각합니다.
Blorgbeard
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.