19P by neo 1달전 | favorite | 댓글 3개
  • "비실용적", "학문적", "니치하다"

    • 사람들이 내가 가장 좋아하는 프로그래밍 언어가 Haskell임을 알았을 때 보이는 반응임
    • 취미 프로젝트뿐만 아니라 실제 웹 서버를 구축하는 데도 사용함
    • Converge에서 Haskell로 작업하는 팀들을 이끌고 있음
  • Haskell에 대한 오해

    • 범용 프로그래밍 언어로 해결할 수 있는 문제는 다른 언어에서도 해결 가능함
    • Python, Rust, Typescript 등에 도입되는 많은 기능들이 Haskell에서 영감을 받았거나 더 견고하게 구현되었음
    • "지루한 기술을 선택하라"는 이념의 변형으로 보임
    • 프로그래밍은 수학이 아니며, 수학적인 요소를 배제해야 한다는 잘못된 생각이 있음
  • 이 글의 목적

    • Haskell이 대부분의 프로그래머에게 최고의 선택인 이유를 논리적으로 설명하려 함
    • 견고한 소프트웨어를 생산적으로 작성하고자 하는 사람들에게 특히 유용함
    • 소프트웨어 작성의 재미있는 측면도 강조함
  • 언러닝과 리러닝

    • 대부분의 프로그래머는 명령형 패러다임에 익숙함
    • Haskell은 순수 함수형 언어로 학습 곡선이 가파름
    • Haskell 언어 자체는 단순한 부분집합으로 제한하면 배우기 쉬움
    • 함수형 프로그래밍은 프로그램을 구성하는 방법에 대한 완전한 전환을 요구함
    • 이 과정은 프로그래머로서 성장하는 데 도움이 됨
    • Alan Perlis의 말 인용:

      프로그래밍에 대한 생각에 영향을 주지 않는 언어는 알 가치가 없음.

문법에 대한 간단한 설명

  • ::는 타입 시그니처를 나타냄 (예: myThing :: String)

  • 함수 호출은 괄호를 사용하지 않고 함수명 뒤에 인수를 공백으로 구분하여 나열함 (예: doSomething withThis withThat)

  • 타입 시그니처에서 소문자는 타입 변수이며, 임의의 타입을 나타냄 (예: head :: [a] -> a)

  • 두 종류의 화살표 ->=>가 있음:

    • ->는 함수의 타입을 설명함 (예: add1 :: Int -> Int)
    • =>는 타입 변수에 대한 제약을 설명하며 항상 먼저 옴 (예: add1 :: Num a => a -> a)
  • 주석은 --로 시작함

  • return은 일반 함수이며, 예상하는 의미가 아님

  • do는 명령형처럼 보이게 하는 문법적 설탕임

  • 지역 변수에 값을 할당하는 여러 가지 방법이 있음:

    let x = <something> in  
    <expression>  
    

    또는 x <- <something>

  • 실수를 줄이기

    • 많은 언어에서 코드를 "올바르게" 만들기 위해 많은 테스트 케이스를 작성함
    • Haskell은 타입 시스템과 순수 함수형 프로그래밍으로 이 부담을 크게 줄임
    • Haskell의 강력한 타입 시스템은 프로그램에 대한 구체적인 보증을 제공하고 엄격하게 적용함
    • 타입 시스템의 특징:
      • 널러블 타입이 없음
      • 실패할 수 있는 계산을 표현할 수 있음
      • 패턴 매칭과 완전성 체크
      • 원시 집착을 무료로 회피함
  • 널 값이 없는 것의 이점

    • null 값이 존재하지 않아 값이 예상하는 타입인지 항상 알 수 있음
    • 런타임 오류를 방지하고 오류 표면을 줄임
  • 실패 가능한 계산의 표현

    • MaybeEither 타입을 사용하여 실패할 수 있는 계산을 명시적으로 표현함
    • Maybe는 결과가 있을 수도 없을 수도 있는 계산을 나타냄
      safeHead :: [a] -> Maybe a  
      
    • Either는 두 가지 값을 가질 수 있음 (Left a 또는 Right b)
      validateAddress :: String -> Either AddressParseError ValidAddress  
      
  • 패턴 매칭과 완전성 체크

    • 모든 입력 도메인을 처리해야 하며, 그렇지 않으면 컴파일러가 오류를 발생시킴
    • 이는 런타임 오류를 방지하고 프로그램의 신뢰성을 높임
  • 원시 집착의 회피

    • newtype을 사용하여 의미론적으로 더 의미 있는 타입을 쉽게 생성할 수 있음
    newtype VenueName = VenueName String  
    newtype EventName = EventName String  
    
  • 순수 함수형 프로그래밍의 장점

    • 데이터가 불변이며, 상태 변이를 걱정할 필요가 없음
    • 부수 효과가 명시적으로 처리되며, 함수는 부수 효과 없이 입력에만 의존함
    • 이는 프로그램의 예측 가능성과 안정성을 높임
  • 부수 효과의 명시적 처리

    • IO 모나드를 사용하여 부수 효과를 코드에서 분리하고 제어함
    • 함수의 타입 시그니처를 통해 부수 효과를 일으키는 함수임을 알 수 있음
    sendGreetings :: User -> IO Response  
    
  • 모나드와 효과 제어

    • 타입클래스와 모나드를 사용하여 함수가 수행할 수 있는 효과를 정확하게 인코딩함
    • 이는 의도하지 않은 부수 효과를 방지하고 코드의 안정성을 높임
  • 생산성 향상 요소

    • 강력한 타입 시스템과 순수 함수형 특성으로 인해 코드 재사용과 개념의 일반화가 용이함
    • FunctorMonoid와 같은 개념을 통해 다양한 데이터 구조에 동일한 패턴을 적용할 수 있음
    fmap (+2) [1, 2, 3] -- [3, 4, 5]  
    fmap (+2) (Just 2) -- Just 4  
    
  • 두려움 없는 리팩토링

    • 컴파일러의 엄격함으로 인해 코드 변경 시 새로운 버그가 발생할 위험이 적음
    • 타입 시스템이 프로그램 도메인을 정확하게 표현할 수 있게 해주어 안심하고 코드를 수정할 수 있음
  • 프로그램에 대한 이해 향상

    • 선언형 프로그래밍으로 문제 도메인을 정확하게 표현할 수 있음
    • 프로그램의 의미를 쉽게 이해하고 신뢰성을 높일 수 있음
    • 불필요한 복잡성을 제거하여 프로그램의 합리적인 추론이 가능해짐
  • 알게브라적 데이터 타입과 타입클래스

    • 도메인에 특화된 언어를 Haskell 내에서 구축할 수 있음
    • 이는 프로그램을 이해하고 유지 보수하는 데 도움이 됨
  • 예시 프로그램

    • 간단한 회계 도구를 작성하여 Haskell의 개념을 실용적으로 적용함

에필로그

  • Haskell을 사용하는 것은 즐겁고 생산적임
  • 강력하고 표현력 있는 타입 시스템과 순수 함수형 프로그래밍의 결합이 Haskell을 특별하게 만듦
  • 다른 언어들도 이러한 기능을 도입하고 있지만, Haskell은 이러한 특징들이 근본에 자리 잡고 있음
  • Haskell을 배우는 것은 프로그래밍에 대한 사고 방식을 변화시켜 줄 것임

GN⁺의 의견

  • Haskell의 학습 가치

    • 프로그래머로서 사고의 폭을 넓히는 데 도움이 됨
    • 함수형 프로그래밍 패러다임을 이해하면 다른 언어에서도 더 나은 코드를 작성할 수 있음
  • 함수형 프로그래밍의 부상

    • 병렬 처리와 동시성에 강점이 있어 현대 컴퓨팅 환경에 적합함
    • 부수 효과의 제어로 인해 예측 가능한 코드 작성이 가능함
  • 다른 언어와의 비교

    • Rust나 Scala와 같이 함수형 프로그래밍을 지원하는 언어들도 있지만, Haskell의 순수성과 타입 시스템은 독보적임
    • 새로운 언어를 배울 때 Haskell의 개념이 도움이 될 수 있음
  • 실무 적용 가능성

    • 초기 학습 곡선은 가파르지만, 투자한 시간만큼 생산성이 향상됨
    • 복잡한 시스템이나 오류에 민감한 도메인에서 유용함
  • 커뮤니티와 생태계

    • Haskell 커뮤니티는 활발하며, 다양한 라이브러리와 도구가 지속적으로 개발되고 있음
    • 오픈 소스 프로젝트에 참여하여 실력을 향상시킬 수 있음

저는 실용성을 얹은 F#에 입문하였습니다

Hacker News 의견
  • Haskell은 부분 함수 대신 전체 함수를 작성하도록 강제함

    • Haskell은 무한 재귀를 방지하지 않음
    • 종속 타입으로 이동하는 FP 생태계에서 타입 검사기가 무한히 실행되지 않도록 하는 것이 중요함
    • Haskell의 많은 임시 확장 기능들이 문제를 일으킴
    • Haskell 철학을 좋아한다면 Haskell에만 국한되지 말아야 함
    • Haskell의 표준화는 실패했음
    • GHC의 고유한 가치 제안은 GHC 런타임 시스템일 수 있음
  • Haskell을 10년 동안 사용해왔으며 도구가 크게 개선되었음

    • ghcup, cabal sandboxing, HLS가 안정적임
    • 라이브러리 생태계에서 부족한 점을 많이 발견하지 못했음
    • Haskell의 컴파일 시간이 여전히 불편함
    • 의존성 컴파일 시간이 길어짐
  • Haskell의 타입 시스템은 함수가 전체임을 증명하지 않음

    • 일반적인 프로그래밍에서는 전체성 증명이 유용하지 않음
    • 대부분의 사람들은 테스트를 통해 프로그램이 실제로 작동하는지 확인함
  • Haskell 언어는 좋지만 생태계는 아직 갈 길이 멀음

    • 컴파일러가 느림
    • 오류 보고 능력이 부족함
    • 첫 번째 오류가 나머지 컴파일을 중단시킴
    • 도구가 다른 함수형 언어에 비해 여전히 부족함
    • 라이브러리 생태계가 부족함
    • Haskell의 아이디어는 다른 많은 언어에 영향을 미쳤음
  • Haskell이나 다른 함수형 언어를 직업적으로 사용하고 싶음

    • Go와 같은 언어는 쉽게 배울 수 있었음
    • 함수형 언어에서 코드베이스를 구축하는 방법을 배우고 싶음
  • Haskell은 프로그래밍 사고방식과 코드 아키텍처에 큰 영향을 미쳤음

    • Haskell의 타입 시스템은 매우 강력하고 이해하기 쉬움
    • Haskell 코드를 미세 최적화하는 것이 재미있었음
    • 도구는 여전히 부족함
  • Haskell은 언어 수준에서 게으름을 실험함

    • 게으름은 표준 라이브러리 수준에서 얻을 수 있음
  • Haskell의 극단적인 순수성과 불변성이 문제임

    • 많은 프로그래머들이 절차적/가변 루프를 더 쉽게 표현함
    • Rust는 유능한 타입 시스템과 많은 함수형 관용구를 사용하지만, 루프와 가변성을 사용할 수 있음
  • Haskell은 비즈니스 로직 소프트웨어(BLOBS)에 매우 적합함

    • 간단한 타입과 패턴 매칭으로 대부분의 비즈니스 로직을 모델링할 수 있음
    • 간단한 부분을 유지하면 비기술적 기여자에게도 쉽게 가르칠 수 있음
    • Haskell은 재미있음

ADT랑 패턴매칭은 좋은데 모나드랑 펑터 소리 좀 안나게 해주세요