함수형 프로그래밍이란

17173 단어 functionaljavascript
소프트웨어 엔지니어로 일하면서 나는 Haskell 또는 Elm과 같은 기능적 언어를 사치스럽게 사용하지 않지만 Elm에서 JavaScript 또는 Python으로 프로그래밍하는 방법을 변경한 많은 것을 배웠습니다. 다음은 3000줄 이상의 Elm 코드를 작성하면서 배운 몇 가지 개념에 대한 요약입니다.

다음은 전적으로 Elm으로 작성된 프로젝트 중 일부입니다.

  • Know Your Theory - 음악 이론 드릴 앱

  • Elm Piano Teacher - 미디 키보드 대화형 도구

  • Music Scale Explorer - 음계의 대화형 그래프

  • Circle of 5ths Explorer - 키 서명과 키보드가 있는 5도의 대화형 원

  • Uke Chord Finder - 대화형 우쿨렐레 코드 찾기

  • FP 어휘



    다음은 함수형 프로그래밍(FP)을 배울 때 나오는 일반적인 용어 목록입니다. 나는 이 기사에서 그들 중 많은 것을 논의할 것이다.
  • 순수 함수
  • 부작용
  • 참조 투명성
  • 변경 가능/불변
  • 카레
  • 모나드
  • 대수 데이터 유형
  • 변형
  • 람다 미적분

  • 순수 함수



    순수 함수란?

    함수는 1) 동일한 인수가 주어지면 항상 동일한 결과를 반환하고 2) 함수에 부작용이 없는 경우 순수하다고 합니다.

    function add(a,b) {
      return a + b;
    }
    function impureAdd(a,b) {
      return a + b + c;
    }
    console.log(add(1,2)) // 3
    // console.log(impureAdd(1,2)) // EXPLOSION!!!
    c = 1
    console.log(impureAdd(1,2)) // 4
    c = 2
    console.log(impureAdd(1,2)) // 5
    


    부작용이란 무엇입니까?



    부작용은 함수에서 반환되지 않은 함수 호출의 결과로 발생하는 것입니다.

    참조 투명성



    함수의 평가가 반환 값으로 대체될 수 있고 프로그램의 동작에 영향을 미치지 않는 경우 표현식은 참조적으로 투명하다고 합니다.

    result = add(2,3) + 5 // result == 10
    result = 5 + 5 // result == 10
    


    대조적으로, 함수 호출을 출력으로 대체할 수 없는 경우 함수는 참조적으로 불투명하다고 합니다.

    For 루프가 없습니까?



    Haskell이나 Elm과 같은 순수 함수형 언어에서는 for 루프가 없음을 알 수 있습니다. map , reducefilter (특히)를 사용하여 모든 목록을 처리해야 합니다.

    list = [1,2,3,4]
    // Imperative
    listTimesThree = []
    for(i = 0; i < list.length; i++) {
      listTimesThree.push(list[i] * 3)
    }
    // Declarative
    listTimesThree = list.map(x => x * 3)
    


    for 루프에서 잘못될 수 있는 모든 것은 무엇입니까?
  • for 루프를 파싱하는 정신적 부담 (그것이 무엇을합니까? 맞습니까?)
  • 스레드가 처리 목록을 변경함
  • 반복자 변수를 변경합니다. i
  • 범위를 벗어난 목록 액세스

  • 카레



    currying is the technique of converting a function that takes multiple arguments into a sequence of functions that each take a single argument.

    Wikipedia Currying


    add = a => b => a + b
    addOne = add(1) // What does this return?
    
    add(1)(2) // 3
    
    list.map(x => addOne(x)) // [2,3,4,5]
    


    카레가 얼마나 유용한가요?

    목록을 렌더링하는 다양한 방법을 제공하는 것은 어떻습니까? Currying을 사용하면 다른 함수에서 함수를 쉽게 만들 수 있습니다.

    list = ['Fries', 'Hamburger', 'Shake']
    
    latexListHead = x => `\\begin\{itemize\}\n${x}\n\\end\{itemize\}`
    latexItem = x => `\\item ${x}`
    
    htmlListHead = x => `<ul>\n${x}\n</ul>`
    htmlItem = x => `<li>${x}</li>`
    
    mdListHead = x => x // The identity function
    mdItem = x => `- ${x}`
    
    renderList = headFn => itemFn => list => headFn(list.map(x => itemFn(x)).join('\n'))
    
    latexList = renderList(latexListHead)(latexItem) // LaTeX render function
    webList = renderList(htmlListHead)(htmlItem) // HTML render function
    mdList = renderList(mdListHead)(mdItem) // Markdown render function
    
    console.log(webList(list))
    console.log(latexList(list))
    console.log(mdList(list))
    


    이제 멋진 웹 목록과 같은 여러 스타일의 목록을 원하면 어떻게 될까요?

    htmlListHead = classes => x => `<ul class='${classes.join(' ')}'>\n${x}\n</ul>`
    
    bigBlueListHead = htmlListHead(['big', 'blue'])
    smallRedListHead = htmlListHead(['small', 'red'])
    
    webList = renderList(bigBlueListHead)(htmlItem)
    
    console.log(webList(list))
    


    다양한 수학 플롯을 생성하는 것과 같이 커링의 다른 용도가 있습니다. 에 내 게시물을 참조하십시오. 그리고 여기는 python file

    예외 던지기는 부작용입니다



    The reasoning is that I consider exceptions to be no better than “goto’s”, considered harmful since the 1960s, in that they create an abrupt jump from one point of code to another. In fact they are significantly worse than goto’s

    1. They are invisible in the source code.
    2. They create too many possible exit points for a function.
    Joel Spolsky at Joel on Software


    이전 블로그 게시물에서 이 주제에 대해 썼습니다.

    자바스크립트 도우미 라이브러리



    JavaScript는 일정하지 않은 API로 악명이 높습니다. 변경할 수 없는 기능은 무엇입니까? 예를 들어 map()는 새 배열을 생성하는 반면 sort()reverse()는 배열을 제자리에서 변형하고 변형된 배열을 반환합니다. 이 불일치는 정신적 부담입니다. 따라서 Ramda 과 같은 라이브러리가 필요합니다.

    list = [4,2,3,1]
    sortedList = list.sort()
    console.log(list) // [4,2,3,1] or [1,2,3,4]?
    


    Ramda's sort 과 비교하십시오.

    JS 라이브러리


  • Ramda
  • neverthrow
  • immutableJS

  • TypeScript 라이브러리


  • purify-ts
  • fp-ts
  • true-myth

  • 기타 리소스


  • [Blog Post] A practical guide to functional programming
  • [YouTube] Why Isn't Functional Programming the Norm? – Richard Feldman

  • [YouTube] Lambda Calculus - Fundamentals of Lambda Calculus & Functional Programming in JavaScript
  • [Blog Post] Some good discussion and some resources
  • 좋은 웹페이지 즐겨찾기