불로장생의 If와 불로장생의 Do

그래서 최근에 나는 Elixir가 굉장함으로 가득 차 있다는 사실을 발견했다. 이것은 당신이 자신의 내부 문법 트리와 쉽게 상호작용을 할 수 있도록 한다(quote). 나는 이것이 매우 멋있는 일이라고 생각한다.

In the simplest of terms macros are special functions designed to return a quoted expression that will be inserted into our application code. -- Elixir Lang


내가 만난 예는 우리가 계산해야 할 표현식이 있다고 가정하는 것이다.
if true do
  "hello world"
end
그러나 때때로 너는 단행 표현식을 쓰고 싶다.문제없어, 친구야, 불로장생약이 너를 보호할 수 있어!
if true, do: "hello world"
이 말은 단지 한 줄뿐이지만, 그것은 나로 하여금 이 때문에 문장을 한 편 쓰기에 충분하다.우리 원인을 깊이 이해하자!
이 점에서 세 가지, 간단한 표현에 주의해야 한다.
  • do 앞에 쉼표가 하나 있습니다.
  • do
  • 다음에 사칭이 있어요.
  • 없음 end 키워드
  • 이 세 가지 힌트는 나를 깜짝 놀라게 했다.
    네가 방금 본 if 성명은?그것은 사실상 언어 키워드가 아니라 일반 함수일 뿐이다.
    네가 방금 본 do구역?언어 키워드도 아니고 키워드 목록입니다 (source code, 기술적으로 키워드 목록 키워드입니다).키워드 목록이 뭔지 모르면 계속 읽어주세요. 제가 더 설명해 드릴게요.

    이 힌트들은 어떤 도움이 됩니까?


    이 힌트들을 다시 한 번 살펴보자. 이 힌트들이 어떻게 우리가 사람들의 시선 속에 숨겨져 있던 진실을 밝히는 데 도움을 주는지 보자!

    1) 쉼표


    이전에 주의를 기울였다면, 첫 번째 힌트는 truedo문장이 분리되어 있음을 가리킨다.
    너는 또 무엇이 헤어졌는지 아니?함수 매개 변수.if문장은 실제로arity가 2인 함수일 뿐이다. 첫 번째는 계산해야 하는 조건이고, 두 번째는 실행해야 하는 조작이며, 쉼표는 두 개의 매개 변수를 구분한다.
    이것은 우리가 앞의 문장을 이렇게 번역할 수 있다는 것을 의미하며, 그것은 여전히 유효하다.
    iex(2)> if(true, do: "hello world")
    "hello world"
    
    내가 하는 일은 그 주위에 괄호를 붙이는 것이다. 그것들은 이제 더 익숙해 보이지 않느냐

    2) 콜론


    두 번째와 세 번째 힌트는 사실상 밀접한 관계를 가진다. 왜냐하면 그들은 모두 키워드 목록을 가리키기 때문이다.
    키워드 목록이 무엇인지, 아니면 어떻게 보이는지 복습해 봅시다.Keyword List의 공식 정의

    A keyword is a list of two-element tuples where the first element of the tuple is an atom and the second element can be any value. - Elixir Lang


    저희가 리스트가 어떤지 알아요. -> [].
    우리는 원조가 어떤 모습인지 안다->{}키워드 목록은 다음과 같습니다.
    [{:atom, "any_value"}]
    
    알겠습니다. 이것은 보기에 좋지 않습니다./입력하기 쉽기 때문에 Elixir는 문법 사탕을 제공하여 이러한 키워드 목록을 작성했습니다.
    [atom: "any_value"]
    
    이 점에서 우리는 이 새로 발견된 논리를 사용하여 이전의 if문장으로 되돌릴 수 있다. 이것은 다음과 같이 바뀔 수 있다.
    iex(2)> if(true, [do: "hello world"])
    "hello world"
    
    다시 한 번, 내가 여기서 한 일은 do 키워드 주위에 네모난 괄호를 추가한 후에 그것들이 무엇인지 알아내는 것이다.
    사실 우리는 키워드 목록의 원시 문법으로 더욱 미치게 할 수 있다.
    iex(2)> if(true, [{:do, "hello world"}])
    "hello world"
    
    만세, 여전히 유효합니다!

    3) 종점은 어디입니까?그리고 증명 시간!


    그래, 내가 이미 너에게 말했지, 그것들은 같은 일이고, 그것들의 작업 원리는 완전히 같지만, 너로 말하자면, 나는 허튼소리를 할 수도 있다. (비록 나는 하지 않을 것을 보증하지만)내 말이 옳다는 것을 증명합시다!
    나는 아직 너에게 세 번째 힌트, 즉 end 키워드가 어디로 갔는지 알려주지 않았다.
    따라서 실제로는 end을 완전히 무시했다. 추상적인 Synax 트리에서 end의 문장을 표시할 필요가 없기 때문이다. 문법 트리 자체에서 추정할 수 있어야 한다.잠시 후, 나는 Elixir의 원본 코드에서 이 방면의 증거를 보여 주었다.
    나는 AST에 대해 너무 많이 이야기하지 않을 것이다. 일부 원인은 그 자체가 완전히 다른 화제이기 때문이다. 그러나 나는 그것에 대한 이해가 아직 부족하기 때문이다.😬) 하지만 빠른 입문/지금까지 제가 알고 있는 것은:

    AST is how the machine understand the flow of code. It builds a tree based on the programming languages' syntax and how machine execution should flow.


    본질적으로 말하자면, 당신은 텍스트 (코드) 를 썼고, 언어는 그것을 이해하려고 시도한 다음, 언어는 현재 이해하고 있는 심지 모델 (추상적인 문법 트리) 을 만들었다.
    내가 서로 다른 표현식을 실행하여 AST를 생성하여 그것들이 똑같다는 것을 증명하는 이유는 코드의 동일성은 어떠한 문법 설탕에 달려 있지 않고 언어가 진정으로 이해하는 내용에 달려 있기 때문이다. 우리의 예에서 이것은 언어의 심리 모델(AST)이다.
    검증할 때가 됐어!
    first = quote do
      if true do
        "hello world"
      end
    end
    # {:if, [context: Elixir, import: Kernel], [true, [do: "hello world"]]}
    
    second = quote do
      if true, do: "hello world"
    end
    # {:if, [context: Elixir, import: Kernel], [true, [do: "hello world"]]}
    
    third = quote do
      if(true, do: "hello world")
    end
    # {:if, [context: Elixir, import: Kernel], [true, [do: "hello world"]]}
    
    fourth = quote do
      if(true, [do: "hello world"])
    end
    # {:if, [context: Elixir, import: Kernel], [true, [do: "hello world"]]}
    
    fifth = quote do
      if(true, [{:do, "hello world"}])
    end
    # {:if, [context: Elixir, import: Kernel], [true, [do: "hello world"]]}
    
    
    우리는 그것들이 서로 같은지 확인하기 위해 마지막 검사를 실행할 수 있다.
    first  == second #=> true
    second == third  #=> true
    third  == fourth #=> true
    fourth == fifth  #=> true
    
    솔직히 말하면, 나는 Elixir가 실제로 어떻게 문장을 계속 읽기/해석하기로 결정했는지 모르겠다. end을 만날 때까지, 나는 또 하나의 완전한 또 다른 주제, 즉 어법 분석, 해석과 표기화가 필요하다고 생각한다. 나는 먼저 이해해야 한다(그리고 AST, 나는 할 수 있지만 아직 없다!)
    하지만!본고를 지원하기 위해 제가 추가할 수 있는 증거는 Elixir가 AST를 문자열(Macro.to_string/1)로 출력할 때 end 단어를 출력된 문자열 as seen from here에 현저하게 추가해야 한다는 것입니다!

    배달


    if true, do: "hello world"
    
    나는 이 줄의 간단한 코드에서 두 가지를 배웠다. 그것은 바로 다음과 같다.
  • if은 하나의 언어 매크로일 뿐이다(case문장으로 확장), 사실상 Elixir의 세계에서 meteprogramming/macros에 관한 새로운 세계가 있다!
  • do은 키워드 목록에 불과합니다.
  • if문장이나 성명함수 등 기본 기능은 특수한 의미를 가진 핵심 언어 기능이라고 생각했지만 Elixir는 AST/키워드 목록 등 기본 기능을 완벽하게 구축하고 이런 기능을 이용하여 다른 기능을 구축할 수 있다.
    이것은 모든 종류의 매크로를 구축할 수 있다는 것을 의미합니다!루비에서 unless 기능을 구축하시겠습니까?Elixir official guide 참조) while 순환을 구축하시겠습니까?너도 이렇게 할 수 있다.
    사실내가 너에게 한 가지 남겨 줄게.def 자체는 하나의 매크로로 defmacro을 사용하여 정의합니다.defmacro 자체는 하나의 매크로로 defmacro을 사용하여 정의합니다.정신 차렸어?만약 네가 그 말을 다시 읽고 싶지 않다면, 네가 이렇게 할 때까지.Read more here .

    저자 설명


    나는 많은 세부 사항(특히 AST에 관해서)을 소홀히 했을 수도 있다. 왜냐하면 솔직히 말하자면, 나는 그것들을 잘 이해하지 못하기 때문이다. (이 글의 중점은 AST에 관한 것이 아니라, 그것들은 단지 문법적 설탕이 없는 상황에서 모두 평등하다는 것을 증명하는 수단일 뿐이다.)
    그러나 이것은 내가 다음에 무엇을 해야 할지 확실하게 알고 있다는 것을 의미한다. 나는 렉서,parser,tokenizer와ast에 대한 더 많은 정보를 알고 싶다. 만약 당신이 그것들에 대한 좋은 자원이 있다면 아래에서 논평을 해 주십시오.⬇️, 나는 정말 그들에게 감격한다!
    P, 저는 Elixir Slack 채널 over here에서 이 점을 알게 되었습니다. Martin Svalin은 모두 등효라고 설명했습니다. 저는 깊이 있게 AST를 탐색하여 그의 견해를 검증하기로 했습니다.스포일러: 그가 옳다!

    좋은 웹페이지 즐겨찾기