아이콘 (프로그래밍 언어)
"오늘의AI위키"의 AI를 통해 더욱 풍부하고 폭넓은 지식 경험을 누리세요.
1. 개요
아이콘(Icon)은 1970년대에 개발된 프로그래밍 언어이다. SNOBOL 언어를 기반으로 하며, 문자열 처리, 목표 지향 실행, 제너레이터, 컬렉션, 문자열 스캐닝 등의 특징을 가지고 있다. ALGOL 계열의 구조적 프로그래밍 언어와 C 또는 파스칼과 유사한 구문을 사용하며, 특히 함수의 성공 또는 실패를 기반으로 하는 흐름 제어가 특징이다. 아이콘은 객체 지향 기능을 포함한 유니콘 언어로 발전하였다. 비판으로는 문자열 처리에 대한 의존성, 프로시저의 기본 실패 설계로 인한 잠재적 오류, 부울 데이터 유형 부재 등이 있다.
더 읽어볼만한 페이지
- 1977년 개발된 프로그래밍 언어 - FP (프로그래밍 언어)
FP는 값을 다른 값으로 매핑하는 함수를 통해 프로그램을 구성하는 함수 수준 프로그래밍 언어이며, 원시 함수와 함수형 연산자를 사용하여 새로운 함수를 만들고 FP84에서 무한 수열과 지연 평가를 포함한다. - 퍼블릭 도메인 소프트웨어 - 미스터리 하우스
미스터리 하우스는 1980년 출시된 어드벤처 게임으로, 그래픽을 도입하여 혁신을 시도했으며, 버려진 저택에서 단서를 찾아 살인자를 밝혀내는 내용을 담고 있다. - 퍼블릭 도메인 소프트웨어 - ANTLR
ANTLR은 EBNF로 표현된 문법을 입력받아 렉서, 파서, 트리 파서 등 다양한 언어 인식기 소스 코드를 생성하는 파서 생성기이며, C#, Java, Python 등 여러 언어를 지원하고 깃허브에 다양한 문법이 공개되어 있다. - 패턴 매칭 프로그래밍 언어 - AWK
AWK는 1977년에 개발된 텍스트 처리 및 프로그래밍 언어로, 유닉스 환경에서 텍스트 처리를 위해 설계되었으며 정규 표현식 처리 기능을 통해 텍스트 분석, 데이터 추출, 보고서 생성 등 다양한 작업을 수행한다. - 패턴 매칭 프로그래밍 언어 - 하스켈
하스켈은 해스켈 커리의 이름을 딴 순수 함수형 프로그래밍 언어로, 여러 함수형 언어 통합 노력의 결과로 탄생하여 느긋한 계산법, 패턴 매칭, 타입 클래스, 모나드 등의 특징을 가지며 GHC가 표준 구현체로 사용된다.
아이콘 (프로그래밍 언어) - [IT 관련 정보]에 관한 문서 | |
---|---|
기본 정보 | |
![]() | |
패러다임 | 멀티 패러다임: 구조적, 텍스트 지향 |
계열 | SNOBOL |
설계자 | 랄프 그리 스월드 |
타이핑 | 동적 |
웹사이트 | Icon 웹사이트 |
발표 연도 | 1977년 |
최신 릴리스 버전 | 9.5.24a |
최신 릴리스 날짜 | 2024년 1월 17일 |
구현체 | Icon, Jcon |
방언 | Unicon |
영향을 받은 언어 | SNOBOL, SL5, ALGOL |
영향을 준 언어 | Unicon, 파이썬, Goaldi, jq |
2. 역사
1971년, 애리조나 대학교 교수가 된 랄프 그리스월드는 벨 연구소에서 개발된 SNOBOL을 연구 도구로 사용하면서 그 한계를 극복하고자 했다. SNOBOL의 구문은 초기 프로그래밍 언어의 영향을 받아 시대에 뒤떨어진 것으로 여겨졌다. 그리스월드는 SNOBOL의 성공/실패 개념을 개선하려 했으나, 그 결과물인 SL5는 만족스럽지 못했다.
1977년, 그리스월드는 SNOBOL4의 철학, SL5의 구문, 그리고 일반화된 프로시저 메커니즘을 제외한 SL5의 기능을 기반으로 새로운 언어 개발을 시작했다. 처음에는 SNOBOL5로 알려졌으나, SNOBOL과의 차이점 때문에 새로운 이름이 필요했다. 여러 이름이 고려된 끝에, Xerox PARC의 그래픽 사용자 인터페이스에 대한 작업을 참고하여 "아이콘"이라는 이름이 채택되었고, 최종적으로 "Icon"으로 확정되었다.
2. 1. SNOBOL
1962년 벨 연구소에서 SNOBOL 프로젝트가 시작되었다.[1] 초기 SNOBOL은 다항식 수식 조작, 기호적 적분, 마르코프 연쇄 연구에 사용되었으나, SCL 언어의 한계로 인해 새로운 언어 개발이 필요하게 되었다.[1] 1963년 IBM 7090에서 실행되는 초기 버전이 개발되었고, 이후 SNOBOL2, SNOBOL3를 거쳐 1965년 SNOBOL4가 출시되었다.[1] SNOBOL4는 가상 머신(SIL)을 기반으로 하여 이식성이 뛰어났으며, 연관 배열(테이블) 등의 기능이 추가되었다.[1]2. 2. SL5와 Icon의 탄생
1971년 8월, 랄프 그리스월드는 벨 연구소를 떠나 애리조나 대학교 교수가 되었다.[4] 그는 SNOBOL4를 연구 도구로 소개하고,[4] SNOBOL을 계속 지원하고 발전시키기 위해 미국 국립 과학 재단으로부터 보조금을 받았다.[5]SNOBOL의 구문은 FORTRAN, COBOL과 같은 초기 프로그래밍 언어의 영향을 받아 열 의존적이었고, 제어 구조는 블록 대신 분기(goto)에 의존했다. 1970년대 초, SNOBOL4의 구문은 시대에 뒤떨어진 것으로 여겨졌다.
그리스월드는 SNOBOL의 성공/실패 개념을 전통적인 흐름 제어 구조를 사용하여 구현하는 작업을 시작했고, 이는 "SNOBOL Language 5"를 의미하는 SL5로 이어졌지만, 결과는 만족스럽지 못했다. 1977년, 그는 새로운 언어를 개발하기 시작하면서 다음 원칙을 기반으로 하였다.
- SNOBOL4의 철학적 및 의미적 기반
- SL5 구문 기반
- 일반화된 프로시저 메커니즘을 제외한 SL5 기능
새로운 언어는 처음에는 SNOBOL5로 알려졌으나, SNOBOL과 상당히 달랐기 때문에 새로운 이름이 필요했다. "C"에 대한 오마주로 "s"를 고려했지만, 문서 조판 문제로 포기되었다. 여러 이름이 제안되고 포기된 후, Xerox PARC가 그래픽 사용자 인터페이스에 대한 작업을 발표하면서 "아이콘"이라는 용어가 사용되기 시작했고, 결국 "icon"으로 변경된 후 최종적으로 "Icon"으로 결정되었다.
3. 언어
아이콘은 ALGOL 계열의 구조적 프로그래밍 언어로, C나 파스칼과 유사한 구문을 가지고 있다. 변수 선언은 필요 없고, 타입은 자동으로 캐스팅된다.
아이콘의 주요 특징은 다음과 같다:
- 목표 지향 평가 (Goal-directed execution): 함수의 "성공" 또는 "실패"를 기반으로 흐름을 제어한다.
- 제너레이터 (Generators): `suspend` 키워드를 사용하여 여러 값을 순차적으로 반환하는 함수를 만들 수 있다.
- 컬렉션 (Collections): 리스트, 테이블(맵 또는 딕셔너리), 집합과 같은 자료구조를 제공한다.
- 문자열 (Strings): 문자열을 문자의 목록으로 취급하며, 문자열 스캐닝(`?`)을 통해 문자열 처리를 간편하게 할 수 있다.
아이콘의 기본 구조는 다음과 같다.
```icon
# 주석
link 라이브러리
procedure main(args)
메인 루틴
end
procedure 함수(인수)
서브루틴
return 서브루틴의 반환값 (생략 가능)
end
```
메인 루틴은 `main` 함수에 기술하며, 서브루틴은 소스 코드의 어느 위치에 작성해도 좋다.
아이콘의 흐름 제어는 함수의 성공/실패 여부에 따라 결정된다. 예를 들어 `read()` 함수가 실패할 때까지 `write(read())`는 계속 실행된다.[5] `if` 문은 조건식이 성공하면 `then` 절을, 실패하면 `else` 절을 실행한다.
제너레이터는 `suspend` 키워드를 사용하여 생성하며, `every` 문을 통해 제너레이터의 모든 값을 반복할 수 있다. 예를 들어 `every write(1 to 10)`은 1부터 10까지 출력한다.
컬렉션에는 리스트, 테이블, 집합 등이 있다. 리스트는 `[]`로 생성하고, `push`, `pop` 함수로 요소를 추가/제거한다. 테이블은 `table(0)`과 같이 생성하며, 키-값 쌍을 저장한다. 집합은 중복되지 않는 값들을 저장한다.
문자열은 문자의 목록으로 취급되며, 부분 문자열 추출, 삽입, 삭제 등의 연산이 가능하다. 문자열 스캐닝(`?`)을 사용하면 문자열 함수를 간편하게 호출할 수 있다. 예를 들어 `s ? write(find("the"))`는 `s`에서 "the"를 찾아 위치를 출력한다.
3. 1. 기본 구문
아이콘은 ALGOL 계열의 구조적 프로그래밍 언어로, C나 파스칼과 유사한 구문을 가지고 있다. 파스칼과 유사하게 할당 연산자로 `:=`를 사용하고, `procedure` 키워드를 사용하며, C 스타일의 중괄호 `{}`를 사용하여 블록을 구성한다. 프로그램은 `main`이라는 프로시저를 실행하여 시작한다.변수 선언은 필요 없고, 타입은 자동으로 캐스팅된다. 숫자는 자동으로 문자열로 변환될 수 있다. 세미콜론`;`으로 끝나지 않는 줄은 의미가 있다면 암시적 세미콜론으로 끝난다.
프로시저는 아이콘 프로그램의 기본 구성 요소이다. 파스칼 명명법을 사용하지만 C 함수처럼 작동하며 값을 반환할 수 있다. 아이콘에는 `function` 키워드가 없다.
아이콘의 기본 구조는 다음과 같다.
```icon
# 주석
link 라이브러리
procedure main(args)
메인 루틴
end
procedure 함수(인수)
서브루틴
return 서브루틴의 반환값 (생략 가능)
end
```
메인 루틴은 `main` 함수에 기술한다. Icon은 한 번 중간 형식으로 컴파일할 때 서브루틴의 형식을 확인한 다음, 다시 컴파일하여 실행 파일을 생성하므로 서브루틴은 선언할 필요 없이 소스 코드의 어느 위치에 작성해도 좋다.
대입식에는 구문 설탕이 있다. 예를 들어, `x := x + n`은 `x +:= n`으로 표기할 수 있다.
블록 구조는 `{}`로 범위를 지정한다.
3. 2. 목표 지향 평가 (Goal-directed execution)
아이콘의 핵심 개념 중 하나는 함수의 "성공" 또는 "실패"를 기반으로 하는 흐름 제어이다. 기존 언어에서는 부울 논리를 기반으로 성공 또는 실패를 테스트하고 분기하는 코드가 필요하지만, 아이콘에서는 이러한 테스트와 분기가 내재되어 있다.[4] 예를 들어, `while a := read() do write(a)`는 `read()`가 실패하지 않는 한 `write(a)`를 호출하고, 그렇지 않으면 중지한다.[5] 성공과 실패는 호출 체인을 통해 전달되므로, 함수 호출을 다른 함수 내에 포함할 수 있다.예시:
while write(read())
위 코드는 `read()` 호출이 실패하면 `write()` 호출이 실패하고, `while`문이 중지된다.[5] 아이콘의 분기 및 루핑 구조는 모두 프로그래머가 제공하는 임의의 부울 테스트가 아닌 내부에 있는 코드의 성공 또는 실패를 기반으로 한다. `if`는 "테스트"가 값을 반환하면 `then` 블록을 수행하고, `&fail`을 반환하면 `else` 블록을 수행하거나 다음 줄로 이동한다. 마찬가지로 `while`은 실패를 받을 때까지 블록을 계속 호출한다. 아이콘은 이 개념을 '''목표 지향 실행'''이라고 부른다.
예외 처리와 달리 실패는 예상된 결과이며, 파일의 끝에 도달하는 것은 예외가 아니라 예상된 상황이다. 아이콘에는 전통적인 의미의 예외 처리가 없지만, 실패는 종종 예외와 같은 상황에서 사용된다.[4]
아이콘은 이 동일한 목표 지향 메커니즘을 사용하여 전통적인 부울 테스트를 수행하지만, 미묘한 차이점이 있다. `if a < b then write("a is smaller than b")`와 같은 간단한 비교는 "조건식, 여기서는 `<` 연산이 성공하고 실패하지 않는 경우"와 같은 의미를 갖는다. `if`는 표현식이 성공하면 `then` 절을 호출하고, 실패하면 `else` 또는 다음 줄을 호출한다. 또 다른 차이점은 `<` 연산자가 성공하면 두 번째 인수를 반환한다는 것이다. 따라서 `if a < b < c`와 같이 연결할 수 있다.
3. 3. 제너레이터 (Generators)
아이콘(프로그래밍 언어)에서 제너레이터는 호출될 때마다 새 값을 반환하는 프로시저이다. `suspend` 키워드를 사용하여 제너레이터를 만들 수 있다.procedure ItoJ(i, j)
while i <= j do {
suspend i
i +:= 1
}
fail
end
위 코드는 `i`에서 시작하여 `j`로 끝나는 일련의 숫자를 반환하는 제너레이터이다. `suspend i`는 실행을 중단하고 `i`의 값을 반환하며, 다시 호출되면 해당 지점에서 실행을 다시 시작한다. 이는 `i <= j`가 실패할 때까지 계속되며, 이 시점에서 블록을 종료하고 `fail`을 호출한다.
얼터네이터(`|`)를 사용하여 여러 값을 생성할 수도 있다.
if y < (x | 5) then write("y=", y)
위 코드는 y가 x 또는 5보다 작으면 y를 출력한다. 내부적으로 얼터네이터는 목록의 끝에서 벗어날 때까지 값을 반환하는 제너레이터이다.
`every` 문은 제너레이터에서 반환된 모든 항목을 반복하고 실패 시 종료한다. `to` 키워드를 사용하여 정수 제너레이터를 구성할 수 있다.
every write(1 to 10)
위 코드는 1부터 10까지 출력한다.
`every` 연산자는 `while`과 유사하며, 제너레이터에서 반환된 모든 항목을 반복하고 실패 시 종료한다.
every k := i to j do
write(someFunction(k))
`every`와 `while`의 주요 차이점은 `while`은 실패할 때까지 첫 번째 결과를 다시 평가하는 반면, `every`는 제너레이터에서 다음 값을 가져온다는 것이다.
3. 4. 컬렉션 (Collections)
아이콘은 리스트, 테이블(맵 또는 딕셔너리), 집합 등 여러 종류의 컬렉션 유형을 제공한다. 아이콘에서는 이것들을 '구조'라고 부른다.리스트는 스택이나 큐로도 사용할 수 있다. 빈 리스트는 `[]`를 사용하여 생성하고, `push` 함수로 요소를 추가하며, `pop` 함수로 요소를 제거한다. 예를 들면 다음과 같다.
```icon
lines := [] # 빈 리스트 생성
while push(lines, read()) # 표준 입력에서 읽은 내용을 리스트에 추가
while write(pop(lines)) # 리스트에서 요소를 꺼내서 출력
```
`!` 연산자를 사용하여 생성기를 호출할 수 있다. 예를 들어 `!&input`는 파일이 끝날 때까지 표준 입력에서 계속 라인을 읽는다.
아이콘의 리스트는 서로 다른 유형의 값을 포함할 수 있으며, 다른 구조를 포함할 수도 있다. 예를 들면 다음과 같다.
```icon
aCat := ["muffins", "tabby", 2002, 8]
```
`list` 생성자를 사용하여 더 큰 리스트를 생성할 수 있다. 예를 들어 `i := list(10, "word")`는 "word" 사본 10개를 포함하는 리스트를 생성한다. `weight := aCat[4]`와 같이 위치 기반으로 항목을 조회할 수 있다. 배열 슬라이싱을 사용하여 다른 리스트의 요소에서 새 리스트를 만들 수도 있는데, 예를 들어 `aCat := Cats[2:4]`는 "tabby"와 2002를 포함하는 `aCat`이라는 새 리스트를 생성한다.
테이블은 기본적으로 정수가 아닌 임의의 키를 사용하는 리스트이다. `table(0)`과 같이 생성하며, 알 수 없는 키의 기본값으로 0을 사용한다. 예를 들면 다음과 같다.
```icon
symbols := table(0)
symbols["there"] := 1
symbols["here"] := 2
```
위 코드는 "there"와 "here"라는 키와 값 1과 2로 두 항목을 테이블에 추가한다.
집합은 리스트와 유사하지만, 주어진 값의 단일 항목만 포함한다. `++` 연산자로 두 집합의 합집합, `**` 연산자로 교집합, `--` 연산자로 차집합을 생성한다.
아이콘은 미리 정의된 여러 "Cset"을 포함하는데, `&ucase`, `&lcase`, `&letters`, `&digits`와 같은 4개의 표준 Cset이 있다. 작은따옴표를 사용하여 문자열을 묶어 새 Cset을 만들 수 있다. 예를 들어 `vowel := 'aeiou'`와 같이 사용할 수 있다.
3. 5. 문자열 (Strings)
아이콘에서 문자열은 문자의 목록으로 취급된다. 따라서 제너레이터이며, 느낌표 구문을 사용하여 반복할 수 있다.```icon
write(!"Hello, world!")
```
위 코드는 문자열의 각 문자를 별도의 줄에 출력한다.
부분 문자열은 대괄호 안의 범위 지정을 사용하여 문자열에서 추출할 수 있다. 범위 지정은 단일 문자를 가리키거나 문자열의 슬라이스를 반환할 수 있다. 문자열은 오른쪽 또는 왼쪽에서 인덱싱할 수 있다. 문자열 내의 위치는 1A2B3C4의 문자 '사이'로 정의되며, 오른쪽에서는 −3A−2B−1C0로 지정할 수 있다.
예를 들어:
```icon
"Wikipedia"[1] ==> "W"
"Wikipedia"[3] ==> "k"
"Wikipedia"[0] ==> "a"
"Wikipedia"[1:3] ==> "Wi"
"Wikipedia"[-2:0] ==> "ia"
"Wikipedia"[2+:3] ==> "iki"
```
마지막 예시는 끝 위치 대신 길이를 사용하는 방법을 보여준다.
첨자 지정은 표현식 내에서 lvalue로 사용할 수 있다. 이를 통해 문자열을 다른 문자열에 삽입하거나 문자열의 일부를 삭제할 수 있다. 예를 들면 다음과 같다.
```icon
s := "abc"
s[2] := "123"
s now has a value of "a123c"
s := "abcdefg"
s[3:5] := "ABCD"
s now has a value of "abABCDefg"
s := "abcdefg"
s[3:5] := ""
s now has a value of "abefg"
```
문자열 처리를 위한 또 다른 단순화는 `?`로 호출되는 ''스캐닝'' 시스템으로, 문자열에 함수를 호출한다.
```icon
s ? write(find("the"))
```
아이콘은 `?`의 왼쪽에 있는 것을 ''주어''라고 지칭하며 문자열 함수에 전달한다. `find`는 첫 번째 매개변수로 검색 텍스트, 두 번째 매개변수로 검색할 문자열을 받는다. `?`를 사용하면 두 번째 매개변수는 암시적이며 프로그래머가 지정할 필요가 없다. 여러 함수를 순차적으로 단일 문자열에 호출하는 경우, 이 스타일은 코드 길이를 줄이고 가독성을 향상시킬 수 있다. 아이콘 함수 서명은 정의에서 주어 매개변수를 식별하므로 호이스팅할 수 있다.
`?`는 구문 설탕의 한 형태이며, 모든 문자열 연산을 위한 "문자열 스캐닝 환경"을 설정한다. 이는 내부 변수 `&subject`와 `&pos`를 기반으로 한다. `&subject`는 원래 문자열에 대한 포인터이고, `&pos`는 문자열 내의 현재 위치(커서)이다. 아이콘의 문자열 조작 프로시저는 이 변수들을 사용하므로 프로그래머가 명시적으로 제공할 필요가 없다. 예를 들어:
```icon
s := "this is a string"
s ? write("subject=[",&subject,"], pos=[",&pos,"]")
```
위 코드는 다음과 같은 결과를 생성한다.
```text
subject=[this is a string], pos=[1]
```
내장 함수와 사용자 정의 함수를 사용하여 스캔 중인 문자열 내에서 이동할 수 있다. 모든 내장 함수는 스캐닝 구문을 사용하기 위해 기본적으로 `&subject`와 `&pos`를 사용한다. 다음 코드는 문자열에서 공백으로 구분된 모든 "단어"를 작성한다.
```icon
s := "this is a string"
s ? { # 문자열 스캐닝 환경 설정
while not pos(0) do { # 문자열의 끝을 테스트
tab(many(' ')) # 모든 공백 건너뛰기
word := tab(upto(' ') | 0) # 다음 단어는 다음 공백까지 또는 줄의 끝
write(word) # 단어 쓰기
}
}
```
이 예제에서는 `pos`, `many`, `tab`, `upto` 함수가 도입되었다. `pos`는 `&pos`의 현재 값을 반환한다. `&pos`는 변수이므로 프로시저 `pos`가 할 수 있는 `&fail` 값을 가질 수 없다. 따라서 `pos`는 아이콘의 목표 지향적 흐름 제어를 쉽게 사용할 수 있도록 하는 경량 래퍼를 제공한다. 이 경우 테스트는 "&pos가 0인가"인데, 아이콘의 문자열 위치에서 줄의 끝이다. 0이 ''아니라면'' `pos`는 `&fail`을 반환하며, `not`으로 반전되고 루프가 계속된다.
`many`는 현재 `&pos`에서 시작하는 제공된 Cset 매개변수의 하나 이상의 예제를 찾는다. 공백 문자를 찾고 있으므로, 이 함수의 결과는 `&pos` 이후의 첫 번째 비공백 문자의 위치이다. `tab`은 `&pos`를 해당 위치로 이동하며, `many`가 문자열의 끝에서 벗어나는 경우 `&fail`이 발생할 수 있다. `upto`는 `many`의 반대이며, 제공된 Cset 바로 앞의 위치를 반환하며, `tab`을 사용하여 `&pos`를 설정한다. 선택은 줄의 끝에서도 멈추기 위해 사용된다.
이 예제는 마침표, 쉼표, 구두점, 탭, 줄 바꿈이 없는 공백 등 "단어 분리" Cset을 사용하여 더 강력하게 만들 수 있다. 해당 Cset은 `many` 및 `upto`에서 사용될 수 있다.
다음은 생성기와 문자열 스캐닝의 통합을 보여주는 예제이다.
```icon
procedure main()
s := "Mon Dec 8"
s ? write(Mdate() | "not a valid date")
end
# 날짜가 유효한지 검사하는 함수를 정의한다.
procedure Mdate()
# 일부 초기 값 정의
static dates
static days
initial {
days := ["Mon","Tue","Wed","Thr","Fri","Sat","Sun"]
months := ["Jan","Feb","Mar","Apr","May","Jun",
"Jul","Aug","Sep","Oct","Nov","Dec"]
}
every suspend (retval <- tab(match(!days)) || # 요일과 일치
=" " || # 공백 뒤
tab(match(!months)) || # 월 뒤
=" " || # 공백 뒤
matchdigits(2) # 최소 2자리 숫자 뒤
) &
(=" " | pos(0) ) & # 공백 또는 문자열의 끝
retval # 마지막으로 문자열 반환
end
# n자리의 문자열을 반환하는 일치 함수
procedure matchdigits(n)
suspend (v := tab(many(&digits)) & *v <= n) & v
end
4. 유니콘 언어
1996년에 객체지향 개념을 포함한 아이콘의 변형 '''아이돌'''(idol) 언어가 만들어졌고, 지금은 유니콘(Unicon)으로 이름이 변경되었다.[1]
유니콘은 다음과 같은 클래스 정의 문법을 제공한다.
- package: 패키지 이름
- class: 클래스 이름, 슈퍼클래스, 속성
- method: 메서드 정의
- initially: 초기화 블록
5. 비판
로렌스 트랫은 아이콘의 몇 가지 문제점을 지적했다. 프로시저가 기본적으로 실패하도록 설계된 것은 제너레이터에는 적합하지만 일반 프로시저에는 잠재적인 오류의 원인이 될 수 있다.[1] 예를 들어 `write(f(-1))`는 예상대로 출력되지 않고, `x := f(-1); write(x)`는 10을 출력한다. 대화형 디버거에서도 코드가 호출되지만 `x`가 예상 값을 얻지 못해 명확하지 않다. 트랫은 아이콘 프로그램 검토 결과 대다수의 프로시저가 제너레이터가 아니라는 것을 발견했다. 즉, 아이콘의 기본 동작은 극소수의 구조에서만 사용되고, 다른 구조에서는 잠재적 오류의 원인이 된다.[1]
또 다른 문제는 부울 데이터 유형과 일반적인 부울 논리가 없다는 것이다. 성공/실패 시스템은 값을 확인하는 경우 대부분 작동하지만, 간단한 코드에서 이상한 동작을 초래할 수 있다.[2] 예를 들어, `if c then { write("taken") }` 프로그램은 "taken"을 출력한다. 왜냐하면 테스트 `c`가 값을 반환하기 때문이다. 그 값은 초기화되지 않은 모든 변수의 기본값인 `&null`이다.[3] `&null`은 유효한 값이므로 `if c`는 성공한다. 이를 테스트하려면 `c === &null`과 같이 명시적으로 해야 한다. 트랫은 "c가 0인가" 또는 "c가 존재하는가"를 테스트하는 것이라고 잘못 추정하면서, 자기 문서화 코드를 손상시킨다고 추정했다.[2]
6. 예제
다음은 문자열의 각 단어를 하나씩 출력하는 예제이다.
s := "this is a string"
s ? { # Establish string scanning environment
while not pos(0) do { # Test for end of string
tab(many(' ')) # Skip past any blanks
word := tab(upto(' ') | 0) # the next word is up to the next blank -or- the end of the line
write(word) # write the word
}
}
참조
[1]
웹사이트
Update version to 9.5.22e
https://github.com/g[...]
2024-01-26
[2]
웹사이트
Goaldi
https://github.com/p[...]
[3]
웹사이트
PEP 255 – Simple Generators
https://www.python.o[...]
Python Software Foundation
2012-02-09
[4]
웹사이트
Array.prototype.indexOf()
https://developer.mo[...]
2023-06-27
[5]
웹사이트
SNOBOL - Introduction
https://try-mts.com/[...]
2015-07-26
본 사이트는 AI가 위키백과와 뉴스 기사,정부 간행물,학술 논문등을 바탕으로 정보를 가공하여 제공하는 백과사전형 서비스입니다.
모든 문서는 AI에 의해 자동 생성되며, CC BY-SA 4.0 라이선스에 따라 이용할 수 있습니다.
하지만, 위키백과나 뉴스 기사 자체에 오류, 부정확한 정보, 또는 가짜 뉴스가 포함될 수 있으며, AI는 이러한 내용을 완벽하게 걸러내지 못할 수 있습니다.
따라서 제공되는 정보에 일부 오류나 편향이 있을 수 있으므로, 중요한 정보는 반드시 다른 출처를 통해 교차 검증하시기 바랍니다.
문의하기 : help@durumis.com