Profile img

Ailrun (UTC-5/-4)

@ailrun@hackers.pub · 3 following · 44 followers

소개 - Who Am I?

  • 개발자/연구원
  • Haskell Language Server Admin
  • PL Theorist
  • Logician
  • 중증 맥덕

근황 - Recent Interests

  • 언어간 상호운용성(Interoperability) 연구 중
  • 의존적 형이론(dependent type theory) 연구 중
  • 효율적인 레이텍 조판(LaTeX Typesetting) 공부 중
  • Québec 에서 제일 맛있는 Stout 마시는 중
GitHub Page
ailrun.github.io/ko
GitHub
@Ailrun

@lionhairdino 예를 들면 "다양한 시선에서 코드를 이해한다"가 지금 공개한 연작의 2 편에서 논건 대수를 통한 계산의 이해와도 밀접한 연관이 있다고 읽혔습니다. 원래 두번째 주제에 대해서 쓰다가 방향성을 틀었네요.

1

@bglbgl gwyng 자연 연역, 즉 함수형 언어에서 (치환을 통해) "더 간단한 증명"을 해서 본문에 등장하는 문제를 피할 수 있는 것처럼 논건(論件) 대수에서도 (cut이 없는) "더 간단한 증명"을 할 수 있다는 이야기였습니다. 본문에서 설명이 조금 부족했던 것 같네요.

1

@ailrunAilrun (UTC-5/-4) 좋은 글 감사합니다!

저런 식의 증명 대신 L에서 x가 등장하는 자리에 M을 치환해넣고, y가 등장하는 자리에 N을 치환해넣은 증명 또한 가능하기 때문이다. 이 직관을 구체화한 것이 바로 다음의 cut 제거 정리이다.

요부분이 좀 헷갈리는데요, 글에서 소개된 Sequent Calculus에서는 치환에 대한 설명이 없는 것으로 보입니다. 함수형 언어에서의 치환에 해당하는 Sequent Calculus에서의 규칙이 추가로 필요한데 생략하신 걸까요, 아니면 글의 내용만으로 설명가능한데 제가 뭔가 놓친걸까요?

@bglbgl gwyng 자연 연역, 즉 함수형 언어에서 (치환을 통해) "더 간단한 증명"을 해서 본문에 등장하는 문제를 피할 수 있는 것처럼 논건(論件) 대수에서도 (cut이 없는) "더 간단한 증명"을 할 수 있다는 이야기였습니다. 본문에서 설명이 조금 부족했던 것 같네요.

0

논리와 저수준(Low-level) 자료 표현(Data representation)에 대한 글 2 편 중 첫째 편입니다. "논리적이 되는 두 가지 방법"이라는 부제로 논리적 증명을 하는 두 방법론에 대해서 다뤄보았습니다. 이 중 하나의 방법론이 둘째 편의 핵심이 될 예정입니다.



RE: https://hackers.pub/@ailrun/2025/%EB%85%BC%EB%A6%AC%EC%99%80-%EC%A0%80%EC%88%98%EC%A4%80-low-level-%EC%9E%90%EB%A3%8C-%ED%91%9C%ED%98%84-data-representation-1-%ED%8E%B8

4
1

논리적이 되는 두 가지 방법 - 논리와 저수준(Low-level) 자료 표현(Data representation) (2 편 중 1 편)

Ailrun (UTC-5/-4) @ailrun@hackers.pub

이 글은 어떤 문장이 "논리적"이라고 할 수 있는지에 대한 심도 있는 탐구를 시작합니다. 일상적인 오용을 지적하며, 진정으로 논리적인 주장은 증명 가능성과 체계의 무모순성이라는 두 가지 핵심 조건을 충족해야 한다고 주장합니다. 특히, "좋은 가정 아래" 논리성을 증명하는 두 가지 방법, 즉 함수형 언어와 유사한 구조를 가진 자연 연역과, 약간의 "부정행위"를 통해 무모순성을 쉽게 보일 수 있는 논건 대수를 소개합니다. 글에서는 명제와 판단의 개념을 명확히 정의하고, 자연 연역을 통해 논리적 증명을 구축하는 방법을 상세히 설명합니다. 특히, 자연 연역과 함수형 언어 간의 놀라운 유사성, 즉 커리-하워드 대응을 통해 논리적 사고와 프로그래밍 언어 이해 사이의 연결고리를 제시합니다. 또한, 자연 연역의 한계를 극복하고 무모순성을 보다 쉽게 증명할 수 있는 논건 대수를 소개하며, 자연 연역과의 구조적 차이점을 강조합니다. 이 글은 논리적 사고의 깊이를 더하고, 프로그래밍 언어와 논리 간의 관계에 대한 흥미로운 통찰을 제공합니다. 특히, 커리-하워드 대응을 통해 논리와 프로그래밍이 어떻게 연결되는지 이해하고 싶은 독자에게 유익할 것입니다.

Read more →
12

말씀하신 것들을 보아 몇몇 분들은 실제 내용 측면에서는 논리와 저수준 자료표현에 더 관심을 가질 분들이 있는 것 같아 전자를 (먼저?) 다뤄보도록 하겠습니다. 2 편으로 나눠져 올라갈 예정입니다.

6

완전한 검정 배경에 하얀 글자는 대비가 높아, 눈에 잔상이 남습니다. 눈의 피로를 덜기 위해 다크 모드를 주 톤으로 선택했다면, 대비를 적당 수준으로 낮춰야 합니다. 나이가 올라갈 수록 영향을 받습니다. 모르시는 분들이 많은 것 같습니다.

2
3
9
1

답 댓글이 아니라, 질문 댓글입니다. 레코드 업데이트 하는 동안에 반드시 레코드 타입을 먼저 알아야 한다는 게 "정상"이라는 거지요?

bar :: T Int
-- bar = emptyT --- 허용
bar = emptyT { x = [3] } --- 레코드 업데이트 중에는 타입 specialize를 못하니 불가

@bglbgl gwyng

1
1

https://gitlab.haskell.org/ghc/ghc/-/wikis/migration/9.6#superclass-expansion-is-more-conservative

내가 9.4 -> 9.6 마이그레이션에서 겪고 있는 문제가 이거랑 관련이 있는거 같은데(확실치 않음)... 9.4에서는 c :: Type -> Constraint 일때 forall c. c Int 뭐 이런 조건이 있으면, 모든 c에 대해 c Int가 존재하는게 말이 안되는데도 실제로 c Int 꼴로 쓰이는 c만 고려해서 타입체크를 통과시켜줬던거 같다(이것도 확실하지 않음). 근데 9.6에선 당연히 거부당한다.

위의 내 이해가 맞다면 9.4의 constraint solving 완전 무근본이었단건데, 이건 또 믿기 어렵다(하스켈의 설계 결정에 대한 신뢰 유지한다고 하면). 어디서 내가 잘못 파악한거지.

@bglbgl gwyng 이 변화는 Paterson-smaller 제약들(Constraints), 즉 어떤 정렬 순서(Well-order)에 의해 더 작은 제약들만 확장하겠다는 확장 순서의 변화고, 이를 제외하면 양상자(quantifier)와의 상호작용은 크게 변하지 않았습니다. 따라서 설명하신 것과는 다른 방식으로 오류가 발생하게 되지 않았나 싶습니다.

3

adjoint도 두 개가 짝을 이뤄 뭔가를 완성하는 느낌이 있었는데, dual도 뭔가 시스템이 완성?안정?된 느낌도 들고 그러네요.
아직 콕 짚지는 못하지만, 프로그램 설계할 때, 기계적으로 따르기만 해도 도움이 될 것 같은 요소가 있을 것만 같아서, 가끔 이해하고 싶은 욕구가 생기는데, "화살표를 싹다 뒤집으면 듀얼"이야 같은 말로는 응용할 수 있을만한 이해에 도달을 못하고 있습니다. 인문학스런 해석 질문은 그만 드려야겠지요. @ailrunAilrun (UTC-5/-4)

@lionhairdino 쌍대는 너무 일반적인 개념이라 쌍대 자체를 응용하기에는 구체성이 모자라고요, 어떤 것의 쌍대를 이용할 것인가를 살펴봐야지요. 이를테면 A의 쌍대를 A -> Void로 생각할 때에는 쌍대의 쌍대가 (A -> Void) -> Void, 즉 Continuation Passing Style에 해당하는 변환을 주지요.

1

아하!하고 답 달려고 고민했는데, 역시나 어렵네요. 둘이 서로 반쪽같은 것들로, 둘을 가지고 있으면 뭔가 되는 그런 "느낌"이라고 뿐이 감이 안오네요. 0에서 +1로 갔다가 -1로 오면 "역"이지만, 0에서 +1로 가고, 0에서 -1로 가는 건 듀얼로 볼 수 있겠지요? 똑 떨어지지 않는 인문학 같아요. @ailrunAilrun (UTC-5/-4)

2

얼마 전에 LaTeX에 2020년에(;;) 추가된 NewDocumentCommand에 대해 알게됐는데, 왜 이제야 알았는지 억울할 지경이다. 진작부터 편하게 선택 인자의 순번이랑 선택인자 구분자(기본은 []인 것)를 바꿔가면서 썼다면 얼마나 좋았을까\ldots

3
3
2
1

@lionhairdino @domatdo도막도 함수의 경우에는 그냥 완전히 다른 해석을 하고 있기 때문이라고 보시면 됩니다. 원래의 람다 함수를 기계 수준에서 이해하려고 한다면 함수 정의로 jump하는 개념을 항상 포함하고 있다고 볼 수 있습니다. 이와는 다르게 CBPV는 값과 계산을 나눔으로서 람다 함수를 그냥 빼내기 연산(Pop) 이후 다른 연산을 이어하는 것으로 바꾼 거지요.

1

(비전공자가 볼 내용은 아닌 것 같긴 한데요.) 취미 공부하는 사람의 질문입니다.
"인자를 받는다"는 행위를
"인자를 스택에 넣는다" 와 "인자를 스택에서 빼낸다" 둘 로 쪼개어
보는 아이디어에서 시작하는 것으로 보면 되나요?
그래서 adjoint란 용어가 아른 거리는 건가 싶습니다.

람다식을, 인자가 아직 들어오지 않아 reduce할 게 없는 으로 볼 때는
[1.인자를 스택에 push ---2.인자를 스택에서 pop] 이 없어 reduce할 게 없는 상태로 봤는데,
CBPN에선 [2.인자를 스택에서 pop]은 있고, 이 걸로 reduce할 게 있는 상태.
로 본다는 얘기인가요?

위 설명에서 질문하고 싶은 것도 한 가득이고, @domatdo도막도 님의 이어지는 질문도 어렵긴 한데, 뭔가 전부는 아니더라도 "제가 필요한 정도"의 것은 건져갈 게 보이는 것 같아 질문드립니다.
@ailrunAilrun (UTC-5/-4)

@lionhairdino @domatdo도막도 함수의 경우에는 그냥 완전히 다른 해석을 하고 있기 때문이라고 보시면 됩니다. 원래의 람다 함수를 기계 수준에서 이해하려고 한다면 함수 정의로 jump하는 개념을 항상 포함하고 있다고 볼 수 있습니다. 이와는 다르게 CBPV는 값과 계산을 나눔으로서 람다 함수를 그냥 빼내기 연산(Pop) 이후 다른 연산을 이어하는 것으로 바꾼 거지요.

2

@domatdo도막도 그 둘은 같습니다만 thunk에 congruence rule이 없습니다. 즉 M = L이어도 thunk(M) = thunk(L)인 것은 아닙니다. (M을 계산한 결과가 L인 경우, thunk(M)은 지연된 계산이기 때문에 더이상 평가가 진행되지 않아 thunk(L)이 될 수 없습니다.)

1

@domatdo도막도 thunk . force가 좀 난해한 녀석이죠. thunk를 LISP의 quasi quotation으로, force를 back quotation으로 이해하면 thunk . force는 항등입니다만, thunk를 그냥 지연된 계산으로 이해하면 thunk (M)은 지연된 M 계산이고 thunk (force (thunk (M)))은 지연된 force (thunk (M)) 계산이라 같다고 하기 미묘합니다. 이 맥락에서 같다는 두 프로그램이 실행되어서 문법적으로 동일한 결과 값을 준다는 이야기일 때요.

1
1
1
1

@domatdo도막도 수반 논리(Adjoint Logic)에 기반한 언어간 상호운용성(interoperability)입니다. CBPV를 이 관점에서 이해하면 계산 언어와 값 언어간의 상호운용성을 특정한 방식으로 구현했다고 볼 수 있습니다. CBPV가 수반 논리보다는 제한적인 대신 그 제한이 기계 수준에서 이해하는데는 유용한 점이 있다고 비교해 볼 수 있겠네요.

3
2
2

Hackers' Pub의 문제는 아니고 Firefox랑 Linux 한글 입력기랑 JS기반 입력기의 환장의 콜라보같은데, 긴 글을 치다보면 한글 입력을 가끔 씹는다. 이를테면 "우주로 가자."고 치는데 "우주로 가." 같이 쳐지는 상황\ldots 써진 걸 확인하면 될 일이지만 약간 "Zone"에 들어가서 정신없이 치다가 한 서너줄 전에 글자 하나 빠진 거 발견하면 아주 돌아버린다\ldots

0

Hackers' Pub의 문제는 아니고 Firefox랑 Linux 한글 입력기랑 JS기반 입력기의 환장의 콜라보같은데, 긴 글을 치다보면 한글 입력을 가끔 씹는다. 이를테면 "우주로 가자."고 치는데 "우주로 가." 같이 쳐지는 상황\ldots 써진 걸 확인하면 될 일이지만 약간 "Zone"에 들어가서 정신없이 치다가 한 서너줄 전에 글자 하나 빠진 거 발견하면 아주 돌아버린다\ldots

2

함수형을 공부하기 전, 함수 작업?의 대상을 {함수, 인자}로만 인식했었는데, {함수, 인자, 적용}으로 인식하기 시작하면서 편해지는 게 많아졌습니다. 그런데 이게 편한 이유가 다른 배경 지식이 생겨서 그런 건지, 이 길로 가는게 쉬운 길이어서 그런 건지는 잘 모르겠습니다. 여기서 시작하면 $<$>가 자연스러워 보였습니다. 혼자 결론에 도달하고는, 누군가가 처음 공부할 때 알려줬으면 좋았겠는데 싶었습니다. 그냥 혼자 생각입니다.

꾸벅 꾸벅 조는 건 완전 동의입니다. 제가 혼자 그 공부하면서 졸았습니다. @xtjuxtapose

2

함수형 언어의 평가와 선택

Ailrun (UTC-5/-4) @ailrun@hackers.pub

이 글은 함수형 언어의 핵심 개념을 람다 대수를 통해 소개하며, 함수형 언어의 평가 방식에 대한 깊이 있는 이해를 제공합니다. 람다 대수의 기본 요소인 변수, 함수, 함수 호출을 설명하고, 값에 의한 호출(CBV)과 이름에 의한 호출(CBN)의 차이점을 명확히 분석합니다. 특히, 폴 블레인 레비의 "값 밀기에 의한 호출(CBPV)"을 소개하며, 이 방식이 CBV와 CBN을 모두 포괄할 수 있는 강력한 도구임을 강조합니다. CBPV가 함수와 함수 호출을 스택 기반으로 어떻게 다르게 해석하는지, 그리고 이를 통해 람다 대수를 기계 수준으로 컴파일할 때 얻을 수 있는 이점을 설명합니다. 항수 분석과 같은 최적화 기법을 CBPV를 통해 어떻게 더 명확하게 표현할 수 있는지 보여주며, GHC 컴파일러의 중간 언어로서 CBPV의 중요성을 부각합니다. 이 글은 함수형 언어의 깊은 이론적 배경과 실제 컴파일러 구현 사이의 연결고리를 탐구하고자 하는 독자에게 유용한 통찰력을 제공합니다.

Read more →
15
3
0

@curry박준규 더 primitive한 의미론을 포착해서 문법 요소로 만들고 그걸로 다양한 정의를 하게 하는게 낫다는 점에선 동의하는데요. 말씀하신 기준을 그대로 적용해버리면, 모든 언어들이(하스켈도 포함) 발전할수록 점점 키워드가 추가되는데, 그때마다 점점 더 안 좋아졌다고 하면 좀 이상하죠.

@bglbgl gwyng @curry박준규 적은 키워드로 표현 가능한 상황이 더 많다면 "디자인(Design)이 더 잘 되었다"고는 할 수 있다고 봅니다. 언어가 발전한다는게 디자인을 개선한다는 것과 직결되어있지 않은 경우가 더 많으니 말입니다. (많은 경우 표현력의 증대나 자주 사용되는 표현의 단순화에 더 집중하죠)

3

@bglbgl gwyng 이게 생각해보니 ‘문법이 복잡하다’, ‘문법 요소가 적다’라는 표현이 구체적이지 않은 것 같습니다. 갑자기 언어 확장이 떠오르면서 ‘문법 안 복잡한 거 맞나?’ 싶네요. 그래서 표현을 좀 바꾸면 저는 사전에 정의된 키워드가 적을 수록 좋다고 생각합니다.

3
2
2
3

[1]에서 문자열을 다룰 때 StrictTextBuilder의 성능을 비교하는 예제에서 Builder의 성능이 더 좋다고 설명한다. 그런데 내 PC에서 같은 코드를 실행했는데 결과가 반대로 나왔다. 이상해서 문자열 길이를 늘렸더니 책에서 말한대로 나왔다.

ghci> concatSpeedTest 50000
0.004451s
0.04721s
ghci> concatSpeedTest 500000
0.062405s
0.023449s
ghci> concatSpeedTest 5000000
0.511402s
0.205632s

  1. Chris Martin, Julie Moronuki, 《Sockets and Pipes》 ↩︎

3

Yacc와 같은 파서 제네레이터에 BNF를 넣으면 파서 코드가 자동으로 생성된다. 그런데 HTTP나 ActivityPub 등의 프로토콜 스펙을 입력으로 넣으면 자동으로 코드를 구현해주는 도구 어디 없나?

6
5
1
1
3

협업을 할 때 미묘하게 거슬리는 것들\ldots

  • 텍스트 파일의 마지막 줄 완성 안 하기 Posix 표준 기준으로 각 줄은 새줄 문자(line feed, '\n')로 끝나야 하며, 마지막 줄도 예외는 아님
  • 그리고 위의 일이 주기적으로 재발할 때\ldots
7

다음 글은 CBPV에 대해서 써볼까 합니다. CBV(Call-By-Value)나 CBN(Call-By-Name)은 전공자라면 한번쯤은 들어봤을 이름이지만, CBPV는 특정 분야 석박사가 아니면 들어본 적 없을 것 같네요. 하지만 실제 컴파일러 구현(GHC지만...)도 논의되고 있는 만큼 앞으로 유명해지지 않을까 싶어 미리 다뤄보려고 합니다.

어이쿠, CBPV가 무엇의 약자인지 써놓지를 않았네요. Call-By-Push-Value의 약자입니다. "Push"가 들어가는 걸로 CBV랑은 완전히 다른 것이 되는데요, 어찌 다른지는 글에서 다뤄보도록 하겠습니다.

3

다음 글은 CBPV에 대해서 써볼까 합니다. CBV(Call-By-Value)나 CBN(Call-By-Name)은 전공자라면 한번쯤은 들어봤을 이름이지만, CBPV는 특정 분야 석박사가 아니면 들어본 적 없을 것 같네요. 하지만 실제 컴파일러 구현(GHC지만...)도 논의되고 있는 만큼 앞으로 유명해지지 않을까 싶어 미리 다뤄보려고 합니다.

6
2
0