스케줄 "공지"를 기다리고 있겠습니다. 기다리는 분이 더 있으니 "공지"가 맞겠습니다.
@ailrunAilrun (UTC-5/-4)
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 일단 일시는 12월 23일 2시인데, 정확한 위치라던지는 아직 모르겠네요.
@ailrunAilrun (UTC-5/-4)
@lionhairdino 싸인 받으러 가도 되나요!
@curry박준규 으악… 싸인이라뇨 ㅋㅋㅋㅋ
@ailrunAilrun (UTC-5/-4)
@hongminhee洪 民憙 (Hong Minhee) 사실 예전에 말씀하신 연구 주제를 처음 들었을때, 쓸모가 확 와닿지 않았어요. 메타프로그래밍을 그냥 CPP 매크로 정도로 생각해서, 그걸 굳이 타입안전하게 해야하나?라고 속으로 생각했는데요. 점차 메타프로그래밍이 생각보다 훨씬 흔한 패턴이란걸 알게됐단 말이죠. 두 프로그램의 상호작용을 기술하거나, Nix에서 쉘스크립트를 다루거나 할때요. 그러면서 그 연구 주제의 중요성을 점점 느끼고 있는 중이에요.
청중이 정확히 어떤 그룹인지는 모르겠지만, 어쩌면 그분들이 저와 비슷한 첫 인상을 가질수 있단 생각이 드네요. 그래서 그런 오해를 피할수 있도록 연구의 응용처를 소개하는데 충분한 시간을 할당하시는게 좋지 않을까 생각이 듭니다.
@bglbgl gwyng 아이디어 감사합니다. 메타프로그래밍 자체의 중요성에 시간을 할애하는 데에는 좀 소홀히 하고 있었는데, 그런 측면에서 자료를 보강해야겠네요
@ailrunAilrun (UTC-5/-4) 오… 청중이 어떻게 될 지 모르겠지만 꽤 어려운 주제 같은데요…!?
@hongminhee洪 民憙 (Hong Minhee) 네, 그래서 세부 내용을 선정하기가 더 어렵네요 ㅎㅎ
@ailrunAilrun (UTC-5/-4) 오… 어떤 주제로 발표하시게 되나요?
@hongminhee洪 民憙 (Hong Minhee) 어떻게 하면 compile time에 metaprogramming의 안전성을 검사할 수 있는가에 대해 좀 학문적인 관점에서 발표할 예정입니다.
@lionhairdino 12월달에 한국에 가서 한답니다. 😀
글투를 넘어 말투를 최대한 부드럽게 상상해보면, 공격적인 글투의 글도, 공손한 조언의 말투처럼 느껴질 때가 있습니다. 확실히 말과는 달리 글에는 많은 컨텍스트를 스스로 채워 넣어야만 합니다. 다 같은 동종 업계 업자끼리 부드럽지만, 지식 알멩이가 있는 대화들이 돌아 다니면 눈이 즐겁습니다. 컨텍스트를 최대한 부드럽게 채워 넣으며 대화가 이어지길 바랍니다.
(말투같은 느낌의 단어로 글투로 쓰다 보니, 살짝 낯설어서 낱말을 찾아 봤습니다. 있긴 있는데, 써 본적이 거의 없는 낱말 같습니다.)
@lionhairdino 글투라는 단어가 있군요. 저는 뭔가 한자어인 "문체"가 더 자연스럽게 떠오르기는 합니다만, 문맥에 딱 어울리지는 않는 단어 같기도 하네요.
이번 겨울에 연대에서 발표를 하나 할 것 같다. 이를 위한 발표자료를 준비 중인데… 완전 대중도 아니고 전문가도 아닌 청중에게 무엇을 어느정도까지 어떻게 설명해야할지… 고민이 많다. 😵💫
@ailrunAilrun (UTC-5/-4) 시간 될 때 반론을 써 보겠습니다.
@xtjuxtapose 반론에 앞서 논지가 혼동되는 것을 막기 위해 분명히하자면, IO의 경우 String을 사용하는 게 나쁜 것은 맞습니다. 그렇지만 그것이 "String을 결코 써서는 안된다"까지 간다면 이는 잘못된 인상(이전 답글에서 언급한 것처럼 "Linked List는 쓰면 안된다"까지에도 비견될 수 있는 인상)을 주는 주장이 된다는 겁니다.
@xtjuxtapose String은 사실 그렇게 느리지 않습니다. Strict Text를 (String이 더 적절한 곳에) 잘못 사용할 경우가 거꾸로 성능하락을 불러올 수 있고, Lazy Text의 경우 surrogate characters를 사용하는 String에 대응하지 못합니다. 물론 "ByteString을 쓰면되지 않느냐?"고 주장할 수는 있지만, 모든 String-like type의 application이 Character 구분을 쉽게 포기할 수 있는 것도 아니죠.
@xtjuxtapose 이게 System IO와 같이 외부와 소통하는 경우는 거의 적용되지 않습니다만, 그렇다고해서 String이 절대로 쓰면 안되는 것이라는 건 "Array가 더 나으니 Linked List는 쓰면 안된다"까지와도 유사한 주장이 될 수 있습니다.
System.IO.readFile 쓰지 마세요.
System.IO.readFile 쓰지 마세요.
System.IO.readFile 쓰지 마세요.
첫째, System.IO.readFile 은 String 을 반환합니다. 이건 심각한 문제입니다. String 을 쓰지 마세요. 외부 세계와 I/O 를 할 때에는 ByteString 을 써야 합니다. 유니코드 문자열을 다룰 때에는 Text 를 쓸 수 있습니다. String 은 시간적으로도 공간적으로 비효율적입니다. 이건 어쩔 수 없습니다. 하스켈은 리눅스 커널보다 오래됐습니다. 그리고 하스켈이 String 을 만들 때에는 아직 하스켈에 모나드도 없던 시절이며, 타입 클래스가 과연 유용하겠는가를 두고 의견이 분분하던 시절이며, 파일 하나가 100 메가바이트가 넘어간다는 것이 과대망상으로 여겨지던 시절입니다. 특히 유니코드보다 더 먼저 나온 언어에 적절한 유니코드 문자열 타입이 있을 수는 없었습니다. 아무튼 String 은 레거시입니다. System.IO.readFile 로 그림 파일을 읽는 프로그래머는 사후세계에서 JPEG XL 파일을 십육진법 표기로 1 바이트씩 읽은 뒤 종이에 그려 내는 형벌에 처해집니다. String 을 쓰지 마세요.
둘째, System.IO.readFile 은 FilePath 를 요구합니다. FilePath 도 사실 String 입니다. 그냥 별명(type synonym)이에요. 이것은 String 이기 때문에 비효율적이며, String 은 문자열이지 바이트열이 아니기 때문에 (인코딩을 전혀 통제할 수 없기 때문에) 파일 경로를 표현하는 타입으로 부적절합니다.
해결책: 먼저 System.OsPath 의 설명을 읽어 보세요. 그리고, file-io 패키지의 System.File.OsPath 모듈을 읽어 보세요. 여기 있는 함수들의 설명을 openBinaryFile 부터 하나씩 읽어보고 쓰세요. 이것들은 파일 경로에 OsPath 를 쓰기 때문에 String 의 비효율이 없고 인코딩도 올바르게 처리할 수 있습니다. 입출력 데이터에는 ByteString 을 씁니다. 바이트열을 유니코드 문자열로 변환할 때에는 예를 들어 Data.Text.Encoding.decodeUtf8Lenient 를 쓸 수 있습니다. 그럼 이제
- 간단히
System.File.OsPath.readFile'에게OsPath를 넘기고ByteString을 효율적으로 받아 와서 국밥처럼 든든하게 메모리에 올려 두고 작업을 하든지 - 전국구 마법사라면 복대는 기본이라고 외치며
withBinaryFile과 앙갓썸 을 Iteratee I/O 로 절묘하게 엮어서 뭔가 개멋있게 하든지 - 하스켈 갓고수이기 때문에 흑마법사답게 보일러실 문을 따고 지하로 들어가 포… 포… 으악! P 로 시작하는 그것을 획득하여 누구도 예상할 수 없는 타이밍에
hGetBuf의 암기를 슉. 슈슉. 슈슈슉. 슉. 날리든지
아무튼 이제는 String 을 놓아주어야 합니다.
@xtjuxtapose String은 사실 그렇게 느리지 않습니다. Strict Text를 (String이 더 적절한 곳에) 잘못 사용할 경우가 거꾸로 성능하락을 불러올 수 있고, Lazy Text의 경우 surrogate characters를 사용하는 String에 대응하지 못합니다. 물론 "ByteString을 쓰면되지 않느냐?"고 주장할 수는 있지만, 모든 String-like type의 application이 Character 구분을 쉽게 포기할 수 있는 것도 아니죠.
@ailrunAilrun (UTC-5/-4) 그런데 부분적으로 닫힌(semi-closed)라는 건 어떤 의미인가요?
@curry박준규 모든 다른operations의 관점에서는 닫혀 있지만 hClose와 file locking의 관점에서는 열려있는 상태를 말합니다. 누군가 handle을 (말하자면) 소유하고 있는 거지요.
하스켈에서 다음과 같은 에러를 만날 경우에
withFile: resource busy (file is locked)
readFile 대신 readFile'을 써보셔요!
readFile은 lazy 버전이고readFile'은 strict 버전입니다!
System.IO 모듈 문서에 다음과 같은 설명이 있습니다.
경고:
readFile연산은 파일의 전체 내용을 모두 소비할 때까지 그 파일에 대해 부분적으로 닫힌(semi-closed) 핸들을 유지한다. 따라서 이전에readFile로 연 파일에 대해(writeFile등을 사용하여) 쓰기를 시도하면, 일반적으로isAlreadyInUseError오류와 함께 실패하게 된다.
@curry박준규 이 에러와는 별개로 withFile의 사용시에는 withFile내에서 필요한 동작을 최대한 다 하는게 불필요한 file handling 작업을 줄일 수 있습니다.
쎄다. 어두일미!를 경험하고 있네요. 도시락으론 쉽지 않은 경험인데 말이지요.
@ailrunAilrun (UTC-5/-4)
@lionhairdino 여기는 생선머리로 만든 카레가 특선요리더라고요
생선도 돔이나 바리계열을 써서 고기가 아주 맛있나보고요 (위에는 돔인 것 같습니다)
오오! 신청 마감을 물어 보신다는 건!
@ailrunAilrun (UTC-5/-4)
@kodingwarriorJaeyeol Lee
@lionhairdino
@kodingwarriorJaeyeol Lee 안타깝게도 다른 일정이랑 겹치는군요...
@ailrunAilrun (UTC-5/-4) 이벤터스 페이지에 적혀있습니다. 발표자 신청과 관련해서는.... 이벤터스 페이지에 연락처가 있으니 그 쪽에 문의하셔도 될 것 같습니다
@kodingwarriorJaeyeol Lee 아, 발표자 신청에 대한 이야기였습니다. 운영 측이신 줄 알았네요.
한국의 함수형 프로그래밍 컨퍼런스 LiftIO 2025가 슬슬 열린다고 한다.
- liftIO 2025 연사 신청 링크: (https://forms.gle/RsmowMdtNxH1Pchc6)
- 컨퍼런스 신청 링크(https://event-us.kr/liftioconf/event/114005)
아, 뭔가 못살게 구는 줄 알았는데, 행사장이 미어 터져서 사람 잡는 거였군요. ㅎㅎ
논문이라 하니, 비전공자는 봐도 모를테고, 미어 터지는 행사장 사진 하나 올려주시지요.
슬... 전공자 경계선에 있는 글 하나 올라올 때 되지 않았나요. 이왕이면 비전공자쪽으로 좀 더 넘어 온 걸로요.
@ailrunAilrun (UTC-5/-4)
@lionhairdino 전남대 최교수님도 만나고 그러고 있답니다.
지금 해야할 일이 하도 많아서 글을 쓰지를 못하네요...
오호, 그들하고 뭔가를 진행하시는군요. 연사로 나서는 건가요?
@ailrunAilrun (UTC-5/-4)
@lionhairdino 아 컨퍼런스에 논문 하나 내서 발표하러 왔는데 사람 밀도가 너무 높아서 ㅋㅋㅋㅋ
International Conference on Functional Programming 이 건가요?
@ailrunAilrun (UTC-5/-4)
@lionhairdino 네 엄청 피곤하게 만듭니다 ㅋㅋㅋㅋ
ICFP는 사람을 죽인다...
생태계에서 툴들이 저마다 파싱하고, 환경 잡고 그러던 게, 이제 한 곳에서 지원할 수 있게 됐다... 라고 보면 되는 건가요? (원래 그렇게 하고 있는 줄 알았습니다.)
@ailrunAilrun (UTC-5/-4)
@lionhairdino 원래는 --with-compiler라고 ghc를 대체하는 녀석을 써야해서 ghc를 흉내내야했는데 이젠 ghci만 흉내내면 된다... 가 된 거지요.
최근 하스켈 리포트를 보니, 언어 서버 지원이 뭔가 바뀌었답니다.
Hannes made hie-bios use Cabal’s
--with-replcommand to load the session, which greatly simplifies the implementation and its treatment of multiple home units
이런 게 있네요. 당연히 --with-repl 로 했어야 하는 것 아닌가, 기존에는 어떻게 했나 찾아보니, 각 툴들이 각자 도생하고 있었다네요. 명확히 동일한 환경으로 언어 서버가 실행되는 줄 알았는데, 아니었나 봅니다.
@lionhairdino 원래 cabal에 --with-repl설정이 없었습니다.
http://logitext.mit.edu/main
재미있는 웹 앱 중 하나. 논건 대수(Sequent Calculus)를 사용해 1차 논리("모든 대상에 대해"나 "어떤 대상이 있어"를 서술할 수 있는 논리)의 명제를 상호작용을 통해 증명해 볼 수 있다.
예를 들어 A /\ B -> A (A 그리고 B이면 A이다)를 증명하려면
- 위 명제를 입력칸에 넣는다.
->를 눌러 명제 안의 "이면"을 증명에서 쓸 수 있는 가정(|-의 왼쪽에 있는 것)으로 바꾼다.- 가정의
A /\B를 눌러 "그리고"의 양 측에 해당하는 가정A와B각각을 얻는다. - 가정이나 결론의
A를 눌러 가정을 사용하는 것으로 증명을 끝낸다.
보다 입문자에게 친절한 설명은 http://logitext.mit.edu/tutorial 에서 읽어볼 수 있다.
약간의 상세가 모자랐다. 위 설명의 첫 단계와 둘째 단계 사이에
- "Prove" 버튼을 누른다
가 빠져있다.
http://logitext.mit.edu/main
재미있는 웹 앱 중 하나. 논건 대수(Sequent Calculus)를 사용해 1차 논리("모든 대상에 대해"나 "어떤 대상이 있어"를 서술할 수 있는 논리)의 명제를 상호작용을 통해 증명해 볼 수 있다.
예를 들어 A /\ B -> A (A 그리고 B이면 A이다)를 증명하려면
- 위 명제를 입력칸에 넣는다.
->를 눌러 명제 안의 "이면"을 증명에서 쓸 수 있는 가정(|-의 왼쪽에 있는 것)으로 바꾼다.- 가정의
A /\B를 눌러 "그리고"의 양 측에 해당하는 가정A와B각각을 얻는다. - 가정이나 결론의
A를 눌러 가정을 사용하는 것으로 증명을 끝낸다.
보다 입문자에게 친절한 설명은 http://logitext.mit.edu/tutorial 에서 읽어볼 수 있다.
@curry박준규 안타깝게도 1978년 이후 50년도 안 되어 "자연어 프로그래밍"이 대세가 되어버렸죠.
@ailrunAilrun (UTC-5/-4) 근데 오히려 타입도 있고 문서화도 잘 되어 있어야 LLM 코딩이 더 잘 되더군요…
@hongminhee洪 民憙 (Hong Minhee) 앗, 그러면 오히려 그렇지 않은 분야에서 LLM을 쓴 게 문제일 수도 있겠군요.
연구자로서, 또한 한 명의 개발자로서 현 세대에 항상 궁금한 것은 AI가 얼마나 도움이 되느냐이다.
Haskell, OCaml은 말할 것도 없고, JavaScript, Python도 AI와 써 본 경험으로는 그들이 큰 도움이 되느냐는 질문에 자신있게 "그렇다"고 하기 힘든 경험만 해봤기 때문이다.
내가 코드의 형식에 대한 집착이 너무 심한 것이 원인일 수는 있겠으나... AI가 준 결과를 여기 바꾸고 저기 바꾸다보면 결국 내가 쓴 처음부터 코드가 된다.
얼핏 드는 생각으로는 거의 "타입도 없고 문서화도 잘 안되어 있는 환경에서는 사람들이 기능을 이해하기 어려우니 AI를 쓰겠다..."싶다가도, "그러면 내가 잘 아는 분야에 대해서 왜 AI를 써야하지?"하는 생각도 떨치기 힘든 상황이 자주 찾아온다.
결과적으로 나는 AI를 사용하려는 시도를 (적어도 일시적으로는) 멈추었다.
Linux가 단어 순서를 맘대로 바꾸어 놓았는데, "내가 쓴 처음부터 코드가 된다."가 아니라 "내가 처음부터 쓴 코드가 된다"를 쓰려 하였다.
연구자로서, 또한 한 명의 개발자로서 현 세대에 항상 궁금한 것은 AI가 얼마나 도움이 되느냐이다.
Haskell, OCaml은 말할 것도 없고, JavaScript, Python도 AI와 써 본 경험으로는 그들이 큰 도움이 되느냐는 질문에 자신있게 "그렇다"고 하기 힘든 경험만 해봤기 때문이다.
내가 코드의 형식에 대한 집착이 너무 심한 것이 원인일 수는 있겠으나... AI가 준 결과를 여기 바꾸고 저기 바꾸다보면 결국 내가 쓴 처음부터 코드가 된다.
얼핏 드는 생각으로는 거의 "타입도 없고 문서화도 잘 안되어 있는 환경에서는 사람들이 기능을 이해하기 어려우니 AI를 쓰겠다..."싶다가도, "그러면 내가 잘 아는 분야에 대해서 왜 AI를 써야하지?"하는 생각도 떨치기 힘든 상황이 자주 찾아온다.
결과적으로 나는 AI를 사용하려는 시도를 (적어도 일시적으로는) 멈추었다.
물론 AI를 굉장히 넓게 보아서 모든 추론 자동화(automated reasoning)가 AI라고 주장한다면 나도 AI를 만드는 사람이기에 AI를 사용하는 것을 피하지는 못하지만 말이다.
연구자로서, 또한 한 명의 개발자로서 현 세대에 항상 궁금한 것은 AI가 얼마나 도움이 되느냐이다.
Haskell, OCaml은 말할 것도 없고, JavaScript, Python도 AI와 써 본 경험으로는 그들이 큰 도움이 되느냐는 질문에 자신있게 "그렇다"고 하기 힘든 경험만 해봤기 때문이다.
내가 코드의 형식에 대한 집착이 너무 심한 것이 원인일 수는 있겠으나... AI가 준 결과를 여기 바꾸고 저기 바꾸다보면 결국 내가 쓴 처음부터 코드가 된다.
얼핏 드는 생각으로는 거의 "타입도 없고 문서화도 잘 안되어 있는 환경에서는 사람들이 기능을 이해하기 어려우니 AI를 쓰겠다..."싶다가도, "그러면 내가 잘 아는 분야에 대해서 왜 AI를 써야하지?"하는 생각도 떨치기 힘든 상황이 자주 찾아온다.
결과적으로 나는 AI를 사용하려는 시도를 (적어도 일시적으로는) 멈추었다.
LaTeX도 쓰면 쓸수록 새로운 기능을 알아갈 수 있는 재밌는 언어인 것 같다.
Type만 있었다면 말이지만...
@curry박준규 all을 다음과 같이 정의하면 문제가 무엇일까요?
all p [] = False
all p [x] = p x
all p (x:xs) = p x && all xs
이 질문에 대한 대답 중 all의 의미에 관한 것이 있을 겁니다. 논리적으로 "모든 ...에 대해"를 어떻게 이해해야 하는냐에 대한 것 말이지요.
공집합을 직접 사용하는 것이 가장 간단한 예시겠지만, 좀 더 논리학에서 자주 사용되는 예시로는 "20세기의 모든 프랑스 왕은 대머리다"가 있겠습니다. 이는 무의미하게 (Vacuously) 참인데요, 왜냐면 19세기를 마지막으로 프랑스에는 더 이상 왕이 없기 때문이지요. 즉, 일반적으로 "모든 ...에 대해"에서 "..." 부분이 (결과적으로) 공집합일 경우 "모든 ..."에 의해 수식된 본문이 어떤 문장인지와는 상관 없이 참이라고 이해한다는 것이지요.
@curry박준규 지금보니 all p xs 대신 all xs라고 썼군요.
Markdown에 형 검사가 필요합니다!
살짝 다른 차원에서 확장해서 바라보는 얘기이긴 한데 그냥 첨언하자면 언어학의 하위 분야인 화용론에서 전제(Presuppositions)라는 주제랑 연결되는 것 같네요. 댓글에 프랑스 왕은 머머리다 예문도 써주신 걸 보니 더욱 더 그런 것 같고요. 간단하게 설명드리자면, 일단 한국어 예문으로 하면 살짝 오해의 소지가 있어[1] 영어 예문을 갖고 쓰면 다음과 같이 생각해볼 수 있습니다.
- P: The King of France is bald.[2]
- Q: There exists an entity that is King of France.
이 때 P의 명제가 참일 수 있는 이유는 Q를 전제로 깔고 가기 때문입니다. 이렇게 Q를 전제로 갖고 가면 P에 부정을 넣어도 (The King of France is not bald 혹은 ¬(The King of France is bald)) 여전히 그 명제는 참입니다. 하지만 실제 현실에서 Q는 거짓입니다. 왜냐하면 오늘날 프랑스는 군주국가가 아니니깐요. 그럼에도 불구하고 P는 여전히 참을 진리값으로 가지죠.
따라서 실제로 전제를 이렇게 정의하기도 합니다 (Levinson, 1983, p. 175).
- A sentence P sematically presupposes a sentence Q iff:
- (a) P ⊨ Q
- (b) ~P ⊨ Q
참고로 여기서 "⊨"는 "함의한다"를 지칭하는 기호입니다 (예: "하스켈은 함수형 언어다."란 문장은 "하스켈은 언어다"란 걸 함의하죠.).
그렇다면 Q가 전제되는 건 알겠는데, 이 진리값이 무엇이느냐에 대한 질문이 생길 수 있습니다. 이에 대해서 언어학자들은 보통 크게 두 가지로 봅니다. 하나는 참으로 간주하는 거고, 다른 하나는 참도 거짓도 아니다라고 보는 거죠. 전자같은 경우엔 어떻게 보면 기계적으로 바라보는 거고, 후자의 경우엔 참/거짓이라는 기존 이치논리(two-valued logic) 혹은 1 또는 0으로 하는 불 논리에서 확장해서 Kleene의 삼치논리(three-valued logic)로 가게 되죠.
참고로 전제 성립 여부 포함 화용론 전체에서 깔고 가는 가장 큰 가정이 하나 있는데, 이 경우에는 바로 해당 발화(utterance) P, 즉 '프랑스왕은 머머리다'라는 명제가 이루어질 때 화자와 청자가 프랑스에는 왕이란 개체가 존재한다(=Q)라고 암묵적으로 서로 동의한다라는 가정입니다.
@icecream_mable구슬아이스크림 언어학과 논리학에서 "전제"로 번역되는 단어가 다르다는 걸 오늘 알았네요. 논리학에서는 premise가 전제고, presupposition은 그와는 별개의 것인데 (번역이 따로 있는지는 모르겠습니다만) 언어학에서는 presupposition을 "전제"로 번역하는군요.
본문으로 돌아가서, 제시하신 문장에서 핵심은 주석에서 언급하셨듯 "the"의 사용에 있겠죠. 영어에서 "the"는 청자와 화자가 암묵적으로 동의할법한 후술하는 대상을 얘기하니까요. 대상을 나타내는 메타 변수 x에 대해 "the" x라는 표현의 presupposition이 existence of x이겠습니다. 억지로 번역해본다면 "그 프랑스 왕은 대머리다"라고 했을 때 청자와 화자가 공통적인 (잘못됐을 수도 있는) 인식인 "프랑스 왕이 (그곳에) 존재한다"를 공유하고 있다고 할 수 있겠습니다.
Ailrun (UTC-5/-4) replied to the below article:
공허한 참
박준규 @curry@hackers.pub
하스켈의 `all` 함수에 빈 리스트를 넣었을 때 왜 `True`가 반환되는지에 대한 의문을 "공허한 참(Vacuous truth)"이라는 개념을 통해 탐구합니다. 흔히 '구현이 그렇게 되어 있으니까'라고 생각할 수 있지만, 저자는 이 현상을 논리적으로 분석합니다. `all` 함수의 구현 방식과, 빈 리스트에 대한 연산 결과가 전체 결과에 미치는 영향을 설명하며, 공집합의 모든 원소가 짝수라는 명제가 참인 이유와 유사한 논리적 근거를 제시합니다. 이를 통해 코드와 수학 간의 연결고리를 발견하고, 마지막으로 ChatGPT가 생성한 유머러스한 이미지를 곁들여 독자에게 즐거움을 선사합니다.
Read more →
@curry박준규 all을 다음과 같이 정의하면 문제가 무엇일까요?
all p [] = False
all p [x] = p x
all p (x:xs) = p x && all xs
이 질문에 대한 대답 중 all의 의미에 관한 것이 있을 겁니다. 논리적으로 "모든 ...에 대해"를 어떻게 이해해야 하는냐에 대한 것 말이지요.
공집합을 직접 사용하는 것이 가장 간단한 예시겠지만, 좀 더 논리학에서 자주 사용되는 예시로는 "20세기의 모든 프랑스 왕은 대머리다"가 있겠습니다. 이는 무의미하게 (Vacuously) 참인데요, 왜냐면 19세기를 마지막으로 프랑스에는 더 이상 왕이 없기 때문이지요. 즉, 일반적으로 "모든 ...에 대해"에서 "..." 부분이 (결과적으로) 공집합일 경우 "모든 ..."에 의해 수식된 본문이 어떤 문장인지와는 상관 없이 참이라고 이해한다는 것이지요.
발음이 재밌는데요. 우리말로 하면 뽀ㄹ겠다에 가깝나 본데요. 언젠가 퀘백가면, 같이 뽀겠다와 흑맥주 달릴까요?
@ailrunAilrun (UTC-5/-4)
@lionhairdino 제가 그때까지 퀘벡에 있는다면 말이지요 ㅋㅋㅋㅋ (아마 박사 졸업하면 옮기지 않을까 합니다)
뭔가 족발 식감 같은 건가요?
@ailrunAilrun (UTC-5/-4)
@lionhairdino 통삼겹구인데 약간 허브향이 쎈 거 상상하시면 되겠습니다
수제 Porchetta는 맛있다
오호, D는 그냥 Day라 하는데, T는 뭘까요?
@ailrunAilrun (UTC-5/-4)
@lionhairdino Time을 줄인 것이라더군요.
해커스 퍼블릭 D-30분..이 아니라 H-30
D Day는 하루 단위로만 쓴다네요.
@lionhairdino 북미에서는 군사용어인 D-는 거의 안 쓰고 천문에서 온 T-를 주로 쓰더군요
(T-5면 5일 남았다는 뜻으로...)
GHCup 오랜만에 다시 설치하는데 못보던 게 생겼다.
GHCup provides different binary distribution "channels". These are collections of tools
and may differ in purpose and philosophy. First, we select the base channel.
[S] Skip [D] Default (GHCup maintained) [V] Vanilla (Upstream maintained) [?] Help (default is "Skip").
@curry박준규 현재는 experimental인 cross build용 channel을 쓰면 GHCJS와 WASM GHC도 설치할 수 있답니다
https://well-typed.com/blog/2025/08/standard-chartered-supports-haskell-ecosystem/
제일은행을 먹은 SC(Standard Chartered)가 하스켈 생태계에 돈을 보태겠다네요. SC가 하스켈을 프로덕트에 조금씩 쓰고 있다는 얘기는 들은 적 있는데... 뭐 얼마나 후원하는지는 자세히는 안나와 있습니다만, 대기업 돈이 들어오면, 긍부정적 변화가 생기긴 하는데.. 툴체인이 정돈된다든지 해서 입문자한테 도움이 되는 변화가 생기면 좋겠습니다. 하스켈을 JS로 트랜스파일링 하는 컴파일러도 있는데, 막상 쓰려고 보면, 난이도가 너무 높아요.
@lionhairdino GHCUp에서 bindist를 지원하기 시작해서 emsdk만 따로 깔면 됩니다.
https://www.haskell.org/ghcup/guide/#ghc-js-cross-bindists-experimental
아직은 experimental이지만 곧 안정화되겠죠 :)
시장 조사 중인 거지요? SMT solver?는 좀 더 전공자용 같고, Lens는 업자도 자주 쓰는 것 같습니다. 언제나 둘 다 쓰자에 한 표지만, 시간 관계상 하나만 쓴다면, Lens에 한 표 던지겠습니다.
@ailrunAilrun (UTC-5/-4)
@lionhairdino 네, 둘 다 틀은 잡아놓았는데, 쓰려하니 둘 다 쓰기에는 시간을 꽤나 잡아먹네요.
Lens에 대해서 글을 써 볼까... 아니면 SMT에 대해서 글을 써 볼까... 이런 고민은 끊이질 않는다 😵
@ailrunAilrun (UTC-5/-4) 고쳐놓도록 하겠습니다!
@hongminhee洪 民憙 (Hong Minhee) 고쳐졌네요! 감사합니다.
Ailrun (UTC-5/-4) replied to the below article:
하스켈 편지
박준규 @curry@hackers.pub
이메일 교환을 요약하면, 한국의 취미 프로그래머 박준규 님이 Haskell에 대한 관심을 표현하며 NRAO의 다니엘 님에게 연락을 시작합니다. 다니엘 님은 Haskell 경험과 NRAO에서의 Haskell 프로젝트(antioch)를 공유하며, 박준규 님의 Haskell 학습 경험과 프로젝트에 대한 질문을 던집니다. 박준규 님은 자신이 관리하는 Hackage 패키지와 Protohackers 문제 풀이 경험을 공유하고, 다니엘 님은 이에 대한 격려와 함께 Typeclassopedia와 free monad를 추천합니다. 이 대화는 Haskell에 대한 열정과 지식을 공유하며, 서로에게 영감을 주는 긍정적인 교류를 보여줍니다. 다니엘 님은 박준규 님에게 Haskell 관련 질문을 언제든지 환영하며, 이 대화를 자유롭게 공유해도 좋다고 허락합니다.
Read more →
@hongminhee洪 民憙 (Hong Minhee) 댓글로 인해 공유되는 글에서는 여전히 AI 요약이 보이네요
웬일이래유... 엘룬님이 다른 분 초대를 다하고.ㅎ
@ailrunAilrun (UTC-5/-4)
@lionhairdino 아 보셨군요. 연구하시는 분도 있으면 좋을 것 같아...
문법 강조가 바뀔 때가 한참 지난 것 같은데, AI가 별의별 걸 다하는 세상에 아직도 눈에 보이는 소식들이 없네요.
예를 들면, 식별자(변수), 함수, 등 문법 요소에 따라 색을 입힌다거나 하는 게 아닌,
전역이냐, 로컬이냐로 색을 달리 한다든지,
오른쪽 우선 결합 연산자면 빨간색, 왼쪽 우선 결합이면 파란색 한다든지,
시맨틱 문법 강조가 일반화 될 때가 된 것 같은데, 혹시 저만 모르고 있는 건가요?
@lionhairdino 아주 대중적까지는 아니어도 LSP server 중에 똑똑한 애들은 어느정도 지원합니다
a = f a 일 때, a를 f의 고정점이라 하니
m a = m (m a) 가 된다면, m a를 m의 고정점이라 할 수 있다.
모나드는 m a = m (m a)가 안되는 것을 join, return의 도움을 받아 성립하게 만든다.
그래서 m의 고정점을 바로 m a라 할 순 없지만, join, return의 도움으로 고정점처럼 동작하게 할 수 있다.
처럼 설명해도 되나 싶습니다.
여러 번 작업 한 걸, 한 번의 작업으로 표현한다.
반대에서 출발해서 보면, 한 번의 작업을 여러 번의 작업으로 인수 분해한다.
이런 목적 측면에서 보면, 고정점도 모나드도 하나의 궤로 설명할 수 있지 않을까 싶습니다.
그냥 상상입니다.
주의: 프로그래머에게도 수학도에게도 쓸모 있지 않은 그저 생각 놀이로, 어제 모임에서 제가 떠들었던 잡담입니다.
튜링 완전한 프로그램은 따로 메모리를 두어 관리하며 돌아가는데, 람다 산법은 이런 메모리가 없는데도 불구하고, 튜링 완전이 할 수 있는 일은 모두 할 수 있다고 합니다. 왜 그럴 수 있는지, 시작 아이디어가 뭘까 생각해 봤습니다. (슬쩍 보기엔, 학문적으로 긴 여정이 있는데, 그 걸 모두 따라가기엔 벅찬 일이라, 절대 따라가고 싶진 않고, 그저 아이디어 정도만 알고 싶습니다.)
함수형에선, 정보를 "기억memory"하는 역할도 역시 함수가 담당합니다. 기억이 필요할 땐 함수 구조를 주어, 기억 공간을 만든다고 볼 수 있습니다. 함수 합성에서 다음 함수의 인자로 새로 바인딩하며 기억의 역할을 합니다. 애초 메모리 모델이 없는 게 아니라, 다른 구조로 메모리 모델을 구현했다고 볼 수 있는 것 아닌가 싶습니다. (이렇게 말하는 곳은 없습니다.)
람다 함수는, "따로 호출할 일이 없어 이름 없는 함수로 정의한다" 쯤으로 넘어가기엔, 숨어 있는 의미가 너무 큽니다. 분명, 이렇게 넘어갈 일이 아닌데, 역시나 친절히 설명해주는 자료를 아직은 못봤습니다. (많이 찾아 보 거나, 깊게 공부한 건 아니라서, 어딘가에는 있지 않을까 싶어요)
람다 함수로 만들어,
- 실행 시점 제어
- 함수 합성 체인 참여
- 필요한 정보들을 모아 두는 단위
- 외부와 소통하는 길을 만들어 둘 수 있고, ...
여기에 기억이라는 중요한 역할도 담당하게 합니다.
람다 산법은 매개 변수, 함수 몸체, 적용, 이렇게 3가지 요소만으로 모든 걸 해결합니다. 알론조 처치 아저씨는 어찌 이런 구조를 떠올렸을까 싶습니다. 애초에 위와 같은 식으로 볼 수 있는 함수 통찰의 눈이 먼저 있었던 상태에서 만든 거겠지요?
@lionhairdino 이런, 말하자면 "저 수준의 상세"가 포함되어있는 체계가 CBPV나 그 아류 체계들이죠.

