# 배열 언어로 사고하기

> Clean Markdown view of GeekNews topic #12867. Use the original source for factual precision when an external source URL is present.

## Metadata

- GeekNews HTML: [https://news.hada.io/topic?id=12867](https://news.hada.io/topic?id=12867)
- GeekNews Markdown: [https://news.hada.io/topic/12867.md](https://news.hada.io/topic/12867.md)
- Type: GN+
- Author: [neo](https://news.hada.io/@neo)
- Published: 2024-01-15T10:15:41+09:00
- Updated: 2024-01-15T10:15:41+09:00
- Original source: [github.com/razetime](https://github.com/razetime/ngn-k-tutorial/blob/main/12-thinking-in-k.md)
- Points: 2
- Comments: 1

## Topic Body

### K 언어로 생각하기

- K 프로그래밍은 대부분 REPL을 통해 이루어짐.
- ngn/k의 rlwrap은 화살표 키로 이력을 탐색할 수 있어 큰 프로그램 개발에 유용함.
- 함수는 REPL에서 테스트 후 실제 코드로 옮겨짐.
- ngn/k의 예쁜 출력은 항상 유효한 K 데이터를 반환하며, 프로그램 속도 향상을 위해 미리 계산할 수 있음.
- K 스크립트는 REPL에 입력한 것처럼 실행되며, 각 줄의 반환값이 세미콜론으로 끝나지 않는 한 출력됨.
- 스크립트는 다중 라인 정의를 허용하여 가독성에 도움이 됨.
- 작업을 스크립트에 저장하고 REPL에서 사용하려면, `\lfile.k`를 사용하여 파일을 실행하고 데이터를 로드할 수 있음.
- REPL에 파일을 여러 번 로드하여 이전 데이터를 덮어쓸 수 있음.
- `\`로 접근하는 REPL 도움말에는 다양한 유용한 명령어가 있음.

### 배열 프로그래밍의 단순화

- 배열 프로그래밍은 복잡한 패턴을 더 작고 선언적이며 읽기 쉬운 패턴으로 단순화하는 지속적인 과정임.
- 복잡한 패턴을 단순화하는 방법은 "APL에서의 패턴과 안티패턴: 초심자의 고원을 탈출하기 - Aaron Hsu - Dyalog '17"에서 자세히 논의됨.

### 행렬 곱셈의 K 변환

- 위키피디아 기사에서 가져온 행렬 곱셈의 반복 알고리즘을 K로 직접 변환할 수 있음.
- K로 변환한 최악의 코드 예시는 많은 전역 변수 할당, 중첩 루프, 많은 수정이 필요함.
- 코드를 단순화하여 이러한 문제들을 하나씩 해결할 수 있음.

### 내부 루프의 단순화

- 내부 루프에서 `sum`을 fold(`/`)를 사용하여 단순화할 수 있음.
- `'` (each)는 배열을 반환하므로 `C` 전역 변수를 제거할 수 있음.
- `i`, `j`, `k` 변수를 제거하여 루프를 단순화할 수 있음.

### 루프 제거 및 전역 변수 최소화

- `k` 없이 직접 행과 열을 매칭하여 중간 루프를 제거할 수 있음.
- `j`를 제거하기 위해 `B`의 각 열을 `A[i]`와 짝지을 수 있음.
- `i`를 제거하기 위해 eachleft를 사용하여 `A`의 각 행을 `B`의 각 열과 짝지을 수 있음.
- 전역 변수가 더 이상 필요 없음.

### 행렬 곱셈 함수의 최종 형태

- `+` (전치)는 비용이 많이 들므로 제거할 수 있음.
- `x`의 각 행을 `y`의 각 열과 곱하는 대신, `B`의 각 행을 `A` 전체에 맞춰 암시적으로 동일한 작업을 수행할 수 있음.
- 최종적으로 간결하고 명시적인 행렬 곱셈 함수를 얻을 수 있음.
- 코드를 단순화하는 과정은 처음에는 여러 단계를 거치지만, K에서의 숙련도가 높아질수록 더 쉽고 직관적으로 될 수 있음.
- 행렬 곱셈은 K의 배열 지원과 잘 맞는 간단한 절차임.
- K와 잘 맞지 않는 더 많은 알고리즘과 그 처리 방법을 미래 장에서 살펴볼 예정임.

**GN⁺의 의견**
- 이 글은 K 언어를 사용하여 행렬 곱셈과 같은 알고리즘을 어떻게 단순화하고 최적화할 수 있는지를 보여줌.
- REPL을 통한 즉각적인 피드백과 코드의 반복적 개선은 K 프로그래밍의 핵심적인 특징으로, 초급 소프트웨어 엔지니어에게도 유용한 학습 방법임.
- 코드 단순화 과정은 프로그래밍 능력을 향상시키는 데 중요하며, 이 글은 그 과정을 구체적인 예시를 통해 이해하기 쉽게 설명함.

## Comments



### Comment 22258

- Author: neo
- Created: 2024-01-15T10:15:41+09:00
- Points: 1

###### [Hacker News 의견](https://news.ycombinator.com/item?id=38981639) 
- 배열 언어의 유용성과 이해 가능성에 대해 여러 사람들이 의문을 제기하고 있음.
  - 배열 언어는 모든 문제에 적합하지 않음.
  - 많은 유형의 문제에 대해 놀라울 정도로 유능함.
  - 배열 언어 사용자들은 대체로 매우 똑똑함.
  - 배열 언어의 작동 방식을 배우는 것은 큰 도전임.
  - 배열 언어에서 "절차적" 코드를 작성하는 것은 매우 나쁜 일임.
  - 암시적 프로그래밍(tacit programming)의 이해는 정신을 확장시키는 멋진 경험임.
  - 동사 연쇄(verb trains)를 내면화할 때의 경험.
  - 배열 기반 언어가 모든 차원의 배열을 다루는 방식의 이해.
  - "under"의 작동 방식 이해.
  - 함수 지수(function exponents) 작동 방식 이해.

- 배열 언어의 놀라운 측면이 많으며, 위의 목록은 그중 일부에 불과함.
  - Aaron Hsu가 병렬 APL 컴파일러를 개발하는 과정을 보며 배열 언어의 실제 잠재력을 확신하게 됨.
  - APL 코드의 "의미 밀도(semantic density)"에 대한 논의.

- 배열 프로그래밍에 대해 들어본 적이 없고 소개를 원한다면 "The Array Cast" 추천.

- 70년대에 APL/APL2를 발견하고 반했지만, 함수를 구성하는 능력에 더 매력을 느낌.
  - Haskell은 순수하고 타입화되어 있어 APL보다 더 재미있고 강력함.
  - APL의 "사고의 도구로서의 표기법"은 과도한 간결함을 정당화하는 논리로 보임.

- 배열 언어 사용에서 가장 중요한 깨달음:
  - 동사는 알고리즘임.
  - 동사(또는 부사)의 연속은 사용해본 가장 직접적인 구성 방식임.
  - 프로그램은 문장과 표현의 집합이 아니라 알고리즘의 구성임.
  - 배열, 맵, 함수에 걸쳐 도메인과 범위를 일관되게 다루는 개념.
  - 코드를 읽을 때 눈이 "뛰어다닐" 필요가 없는 왼쪽에서 오른쪽으로의 평가.
  - 데이터에 코드를 보내는 것이 가능하며 선호됨.
  - K 언어의 추가 이점: 뷰(즉, 의존성)를 직접 구현할 수 있고, 인터프리터를 통한 핫 코드 로딩이 가능함.

- 배열 언어에 대한 질문: "N보다 작은 숫자 중에서 조건 P가 참인 모든 숫자를 찾기"와 같은 작업을 어떻게 수행하는가?
  - 배열 언어에서는 일반적으로 1부터 N까지의 배열을 생성하고, 배열에 대해 조건을 테스트한 후, 조건이 참인 요소만 얻기 위해 마스크를 적용함.
  - N이 크고 조건이 자주 참이 아닐 경우, 불필요하게 많은 임시 배열을 생성하는 것은 메모리와 자원 낭비로 보임.
  - 배열 언어의 구현은 이러한 문제를 최적화하거나, 게으른 평가(lazy evaluation)와 같은 기법을 사용하여 해결할 수 있음.

- J 언어에 대한 경험: 배열 언어의 패러다임이 편향되어 있으며, 모든 문제를 배열의 중첩으로 생각하는 것이 도움이 되는지 확신할 수 없음.
  - 문제를 단순화할 수 있는 데이터 구조를 자유롭게 생성하는 것이 알고리즘 부분을 크게 단순화할 수 있음.
  - APL/J/K를 사용하기 위해서는 이러한 편향 때문에 더 똑똑해야 함.

- K 언어 문제를 풀면서 얻은 인상: K 언어는 의도적으로 난해함.
  - 퍼즐과 영리한 해결책에 적합한 언어지만, Python에서 numpy 배열로 작업하는 것이 배열 언어를 배우고 배열로 생각하는 방법을 가르쳐줌.

- 배열 언어 J의 예시: `dot =: +/ . *`를 사용하여 P와 Q의 점곱(dot product)을 계산함.

- K 언어의 문법이 더 짧지만, K 언어의 작동 방식에 대한 많은 내장된 맥락을 머릿속에 유지해야 함.
