Elixir와 Javascript 문법 비교

일상적인 업무에서 나는 두 가지 언어를 사용한다.Java 및 Javascript
매일 자바스크립트를 작성하고 불로장생의 약을 배우면서 나는 몇 가지 모델을 깨달았다.우리 한번 되돌아봅시다.
웹 개발 별에서 ES6가 자바스크립트 언어에 제공하는 특성, 특히 기능성 특성을 소홀히 하는 사람은 없다.

요약
  • 개체 및 모듈
  • 방법체인과 파이프 조작원
  • 해체와 패턴 일치
  • 고급 함수

  • 대상 및 모듈
    ES6에서는 키워드class와 모든 OO의식Javascript이 나온다.Elixir에서는 함수 언어로서 Object의 개념을 지원하지 않는다. 반대로 우리는 Modules가 있는데 함수로 볼 수 있는bucket이나 명칭 공간이 있다.Object의 예:
    const Circle = {
      PI: Math.PI, // Math.PI is a constant
      area: r => Circle.PI * (r ** 2),
      circumference: r => Circle.PI * (r * 2)
    };
    
    Circle.area(2) // 12.56...
    
    Javascript와 동일:
    defmodule Circle do
      @pi :math.pi() # Here we define a module constant
    
      def area(r), do: @pi * (r * r)
      def circumference(r), do: 2 * @pi * r
    end
    
    Circle.circumference(5) # 31.41..
    
    그래서 내가 보기에 나는 FP에서 작은 함수를 작성하는 좋은 습관을 길렀다. 예를 들어 그들은 전달된 입력과 요청의 수정에 따라 입력과 새로운 출력에 대해 작은 수정을 책임진다.이것이 바로 우리가 말한 감속기다.
    이것은 우리로 하여금 매우 복잡한 데이터 변환을 쉽게 구축할 수 있게 하기 때문에, 이것은 자연히 우리를 다음 단계로 인도한다. 방법 링크와 파이프 조작부호이다.

    한 가지 배경: 이랑과 장생불로약
    한 선례에서 나는 Elixir를 사용했는데 그것은 불로장생약 모듈이 아니었다. 원인은 다음과 같다.:math.pi()와 달리 Javascript는 수학 모듈이 없고 Elixir 표준 라이브러리를 이용한다.사실ErlangElixir 위에 세워진 것이다.그 밖에 ErlangElixir는 상호작용이 가능하다.이것은 우리가 Erlang 코드에서 Erlang 라이브러리의 거대한 생태계를 사용할 수 있다는 것을 의미한다.이거 좋네.
    따라서 Elixir에서 Erlang 모듈을 호출하려면 다음을 입력하면 됩니다.
    :erlang_module.erlang_function()
    :math.pi()
    :crypto.hash(:md5, data) # To use crypto library and hash with MD5
    

    방법 링크와 파이프 조작부호
    여기서 우리는 현실 세계를 예로 삼아 일련의 숫자를 제곱 연산하고 그 값을 하나로 줄일 것이다.그래서 우리는 두 언어에서 맵과 Reduce 함수를 사용할 수 있다.Elixir
    const numbers = [1,2,3,4,5]\
    let sumOfSquares = list
      .map(num => num * num)
      .reduce((num, acc) => acc + num)
    
    Javascript에서 우리는 파이프 조작부호를 사용할 것이다
    list_of_numbers = [1,2,3,4,5]
    sum_of_squares =
      list_of_numbers
      |> Enum.map(&(&1 * &1))
      |> Enum.reduce(&(&1 + &2))
    
    여기에 두 가지가 있는데 Elixir 특정한 것이다. 첫 번째는 Elixiraka pipe 조작부호이고, 두 번째는 이 기이한 문법|>이다.
    따라서 파이프 조작부호는 Unix 셸의 방식으로 데이터를 한 함수에서 다른 함수로 호출할 수 있도록 합니다.하지만, 벤 아저씨가 우리에게 말했듯이 강력한 힘은 엄청난 책임을 가져온다, 음...농담입니다. 여기는 단지 하나의 규칙이 있습니다. 당신의 첫 번째 함수 매개 변수는 전 함수의 출력이어야 합니다.그게 다야.그래서 &(&1)map 중의 Javascript는 모두 하나Elixir 또는 하나Array로 되돌아간다.
    이 파이프 조작부호를 진정으로 이용하려면 반드시 함수 조합을 고려해야 한다.다음은 내가 쓴 간단한 스크레이퍼의 예이다.
    특정 URL에 대한 호출을 수행하고 301 HTTP 상태를 처리하고 올바른 URL을 가져온 다음 올바른 형식의 URL을 새로 호출해야 합니다.
    def get_url(ean) do
        HTTPoison.start()
        url =
          "#{@url}-#{ean}" # Module constant here
          |> HTTPoison.get!() # Call to another Module function
          |> get_html() # Module function
          |> get_title() # Module function
          |> List.to_string() # List Module function call
          |> split() # Module function
      end
    
    그래서 이 파이프 조작부호는 한 가지 일을 피했다. 함수 호출은 다음과 같다.
    function3(function2(function1(data))) // works but we loose readability
    
    파이프 조작원은 데이터를 마땅히 놓아야 할 곳에 두었다.어쨌든 이것은 우리가 가장 주목하는 문제다.
    내 기억에 파이프 업체는 TC39의 제안 단계에 있는 것 같다.어쨌든 ReasonML에서도 사용할 수 있기 때문에 React Reason에서 사용할 수 있습니다.
    만약 내가 너에게 우리가 원하는 것을 설명하기만 한다면, 우리는 변수의 데이터를 쉽게 추출할 수 있다. 그러면 어떻게 될까?

    해체와 패턴 일치List에서 우리는 Elixir라고 말했는데 x = 1x와 같다고 생각할 수 있다.그러나 미묘한 차이점이 하나 있다. 우리는 이것이 평등이라고 말하지 않고, 우리는 이것이 일치한다고 말한다.뒤의 값1x이다. 왜냐하면 우리는 1라는 자유 변수를 귀속시켜 x의 값을 매칭했기 때문이다.그래서 1 기호는 =가 아니라 match operator라고 불린다.
    이를 equalRhs 사이의 비교로 간주하다.우리가 이 점을 어떻게 이용하는지 보자.
    MDN 문서의 경우

    The destructuring assignment syntax is a JavaScript expression that makes it possible to unpack values from arrays, or properties from objects, into distinct variables.


    그래서:
    let a, b, rest;
    [a, b, ...rest] = [10, 20, 30, 40, 50]; // ... or spread operator
    a // 10
    b // 20
    rest // [30, 40, 50]
    
    Lhs:
    list = [1,2,3,4,5]
    a, b = list
    ** (SyntaxError) iex:2: syntax error before: ','
    
    오, 그것은 Elixir에서처럼 그렇게 일하지 않는 것 같아...여기Javascriptlist 유형입니다.List에서 목록은 머리와 꼬리로 구성되어 있다. 예를 들어 Elixir(이곳의 파이프는cons 조작부호라고 부른다).
    따라서 우리는 이렇게 목록을 쓸 수 있다[head | tail].
    이 일을 [1 | [ 2 | [ 3 ]]]방식으로 합시다.
    list = [1,2,3,4,5]
    [a|b] = list
    a # 1
    b # [2,3,4,5]
    
    # One more time
    [a, b, c|d] = list
    a # 1
    b # 2
    c # 3
    d # [4,5]
    
    Elixir에서는 특히 함수 매개 변수에서 해구가 매우 좋다.
    예를 들어 이 React 구성 요소에서 호출되지 않음 Javascript, props.title 등등.
    props 매개 변수를 해체하고 가져올 값을 선택하십시오.
    render() {
      return (
       <div className="directory-menu">
        {
         this.state.sections.map(({title, imageUrl, id, size}) => (
          <MenuItem key={id} title={title} imageUrl={imageUrl} size={size} />
         ))
        }
       </div>
      );
     }
    
    내가 이 props.imageUrl 부분에서 한 바와 같다.
    def draw_image(
      %Identicon.Image{color: color, pixel_map: pixel_map})
      do
        image = :egd.create(250, 250)
        fill = :egd.color(color)
    
        Enum.each pixel_map, fn({start, stop})  ->
          :egd.filledRectangle(image, start, stop, fill)
        end
    
        :egd.render(image)
      end
    
    Elixir 구조에서 값을 추출하기 위해 함수 매개 변수에서 전달된 구조의 필드를 패턴으로 일치시켰습니다.그런데 만약에 우리가 함수 매개 변수에서 함수를 호출할 수 있다면?

    고급 함수Identicon.Image에서 함수는 일등 공민이기 때문에 함수는 함수를 매개 변수와/또는 반환 함수로 할 수 있다.
    평범하지 않은 예를 하나 봅시다!
    // In ES6 style
    const multiplyAll = array => times => array.map(
      item => item * times
    );
    
    // In ES5 style
    var multiplyAll = function multiplyAll(array) {
      return function (times) {
        return array.map(function (item) {
          return item * times;
        });
      };
    };
    
    multiplyAll([2,7,3,60])(2) // [4, 14, 6, 120]
    
    이것이 바로 우리가 말한 것이다🍛 🙌 CURRYFICATION 🍛 🙌!
    ES5 스타일에서 볼 수 있듯이, 우리는 하나의 함수를 되돌려줍니다. 이것은 lambda (또는 익명) 가 있는 방법을 사용합니다.기능!

    형님, 함수를 좋아한다고 들었어요. 그래서 함수를 함수에 넣었어요. 함수체에서 함수를 되돌려줘요...🤔
    사실 이것은 매우 도움이 된다.이런 방식을 이용해 부작용을 방지하고 순기능을 겨냥할 수 있다.Elixir에서 우리는 이렇게 할 수 있다.
    # Here we declare a lambda called run_query
    run_query =
      fn query_def ->
        Process.sleep(2000)    ①  
        "#{query_def} result"
      end
    
    # Here another lambda with the previous one inside.
    async_query =
      fn query_def ->
        spawn(fn -> IO.puts(run_query.(query_def)) end)
      end
    
    # And finally, we use this lambda in another function call
    Enum.each(1..5, &async_query.("query #{&1}"))
    
    # Naively we can achieve this this way
    add = fn x ->
      fn y -> x + y end
    end
    
    add.(1).(3) # 4
    
    Javascript vs Elixir 이 글은 여기서 끝냅니다. 주요 목표는 두 언어 간의 진정한 비교가 아니라 한 언어의 장점을 이용하여 더 좋은 코드를 작성하는 것입니다.
    앞서 말한 바와 같이 제가 장생불로약 여행을 시작한 이후로 장생불로약의 습관적인 용법과 철학을 어떻게 활용하여 더 좋은 자바스크립트를 만드는지 깨달았습니다. 반대로도 마찬가지입니다.
    만약 네가 이 점을 할 수 있다면 정말 좋겠다.

    좋은 웹페이지 즐겨찾기