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


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.