소스 코드 생성은 안티 패턴입니까? 한 올바른 조치를

무언가를 생성 할 수 있다면 코드가 아닌 데이터입니다.

그렇다면 소스 코드 생성에 대한이 전체 아이디어가 오해가 아닙니까? 즉, 무언가를위한 코드 생성기가 있다면, 필요한 매개 변수를 수신하고 “생성 된”코드가 수행 한 올바른 조치를 수행 할 수있는 적절한 함수로 만들 수있는 이유는 무엇입니까?

성능상의 이유로 수행되면 컴파일러의 단점처럼 들립니다.

두 언어를 연결하기 위해 인터페이스 라이브러리가 부족한 것 같습니다.

여기에 뭔가 빠졌습니까?

코드도 데이터라는 것을 알고 있습니다. 내가 이해하지 못하는 것은 왜 소스 코드를 생성 합니까? 파라미터를 받아 들여서 작동 할 수있는 함수로 만들어 보지 않겠습니까?



답변

소스 코드 생성은 안티 패턴입니까?

기술적으로, 코드를 생성 하면 사람이 읽을 수있는 텍스트 인 경우에도 소스 가 아닙니다 . 소스 코드 는 인간 또는 다른 진정한 지능에 의해 생성 된 원본 코드로, 기계적으로 번역되지 않으며 (직접) 간접적으로 (진실한) 소스에서 즉시 재현 할 수 없습니다.

무언가가 생성 될 수 있다면, 그것은 코드가 아니라 데이터입니다.

어쨌든 모든 것이 데이터 라고 말할 것 입니다. 심지어 소스 코드. 특히 소스 코드! 소스 코드는 프로그래밍 작업을 수행하도록 설계된 언어의 데이터 일뿐입니다. 이 데이터는 필요에 따라 다른 형식의 데이터로 변환, 해석, 컴파일 및 생성되어야하며, 그 중 일부는 실행 가능합니다.

프로세서가 메모리 부족 명령을 실행합니다. 데이터에 사용 된 것과 동일한 메모리 프로세서가 명령을 실행하기 전에 프로그램이 데이터 로 메모리에로드됩니다 .

따라서 모든 것이 데이터 이며 심지어 코드 입니다.

[생성 된 코드는 데이터]라는 점을 감안할 때 코드 생성에 대한이 전체 아이디어가 오해가 아닙니까?

컴파일 단계에서 여러 단계를 수행하는 것이 좋습니다. 그 중 하나는 텍스트로 중간 코드 생성이 될 수 있습니다.

즉, 무언가를위한 코드 생성기가 있다면, 필요한 매개 변수를 수신하고 “생성 된”코드가 수행 한 올바른 조치를 수행 할 수있는 적절한 함수로 만들 수있는 이유는 무엇입니까?

한 가지 방법이지만 다른 방법이 있습니다.


코드 생성의 결과물은 텍스트이며 사람이 사용하도록 설계된 것입니다.

모든 텍스트 형식이 사람이 소비하는 것은 아닙니다. 특히, 생성 된 코드 (텍스트)는 일반적으로 사람이 아닌 컴파일러 소비를위한 것입니다 .


소스 코드는 원본으로 간주됩니다. 마스터 — 편집 및 개발; 소스 코드 컨트롤을 사용하여 아카이브하는 것. 사람이 읽을 수있는 텍스트 인 경우에도 생성 된 코드는 일반적으로 원래 소스 코드 에서 재생성됩니다 . 일반적으로 말하면 생성 된 코드는 빌드 중에 재생성되므로 소스 제어를받을 필요가 없습니다.


답변

실용적인 추론

좋아, 나는 코드도 데이터라는 것을 안다. 내가 이해하지 못하는 것은 왜 소스 코드를 생성하는 것입니까?

이 편집에서 나는 당신이 이론적 인 컴퓨터 과학이 아니라 오히려 실질적인 수준을 요구한다고 가정합니다.

Java와 같은 정적 언어로 소스 코드를 생성하는 고전적인 이유는 이와 같은 언어는 언어 도구를 사용하여 매우 역동적 인 작업을 수행하기가 쉽지 않기 때문입니다. 예를 들어, Java의 형성 시대로 거슬러 올라가면 동적 이름 (DB의 테이블 이름과 일치)과 동적 데이터 유형 (동일한 테이블의 속성과 일치) 및 동적 데이터 유형 (일치하는)을 가진 클래스를 쉽게 작성할 수 없었습니다. 상기 속성의 유형). 특히 Java는 컴파일 타임에 유형 오류를 잡을 수 있다는 점에서 매우 중요합니다.

따라서 이러한 설정에서 프로그래머는 Java 코드 만 작성하고 많은 코드 행을 수동으로 작성할 수 있습니다. 프로그래머는 종종 테이블이 변경 될 때마다 돌아가서 코드가 일치하도록 변경해야한다는 것을 알게됩니다. 그가 잊어 버리면 나쁜 일이 일어납니다. 따라서 프로그래머는 자신을 위해 도구를 작성하는 시점에 도달하게됩니다. 따라서 더 지능적인 코드 생성이 시작됩니다.

(예, 바이트 코드를 즉석에서 생성 할 수는 있지만 Java에서 그러한 것을 프로그래밍하는 것은 임의의 프로그래머가 도메인 코드의 몇 줄을 쓰는 것 사이에서하는 것이 아닙니다.)

이것을 매우 역동적 인 언어, 예를 들어 Ruby와 비교하면 대부분의 측면에서 Java에 대한 대립을 고려할 것입니다 (어쨌든 두 가지 접근법을 평가하지 않고 말하고 있음을 유의하십시오. 단순히 다릅니다). 여기에서 런타임에 클래스, 메소드 등을 동적으로 생성하는 것은 100 % 정상 및 표준이며, 가장 중요한 것은 프로그래머가 “메타”레벨로 가지 않고도 코드에서 간단하게 수행 할 수 있다는 것입니다. 그렇습니다. Ruby on Rails와 같은 것들은 코드 생성과 함께 제공되지만, 우리는 기본적으로 새로운 프로그래머를위한 일종의 고급 “자습서 모드”로 사용하지만, 얼마 지나지 않아 코드가 너무 적기 때문에 불필요한 것으로 나타났습니다. 생태계에서 작성하는 작업을 알고있을 때 생성 된 코드를 정리하는 것보다 수동으로 작성하는 것이 더 빠릅니다.

이것들은 “실제 세계”의 두 가지 실제 예입니다. 그런 다음 코드 데이터 인 LISP와 같은 언어가 있습니다 . 반면에, Java 또는 Ruby와 같은 런타임 엔진이없는 컴파일 된 언어에는 런타임에 클래스 또는 메소드 이름을 정의하는 개념이 없습니다. 따라서 코드 생성 빌드 프로세스는 대부분의 경우 선택하는 도구입니다 (다른 C / C ++ 특정 예제는 flex, yacc 등입니다).


답변

왜 코드를 생성합니까?

펀치 카드 (또는 메모장의 대체 코드)로 프로그래밍 하는 것은 고통 스럽기 때문입니다.

성능상의 이유로 수행되면 컴파일러의 단점처럼 들립니다.

참된. 강요받지 않으면 성능에 관심이 없습니다.

두 언어를 연결하기 위해 인터페이스 라이브러리가 부족한 것 같습니다.

흠, 무슨 말인지 모르겠다.

생성되고 유지되는 소스 코드는 항상 그리고 영원히 고통 스럽습니다. 한 가지 이유만으로 존재합니다. 누군가는 한 언어로 일하기를 원하지만 다른 사람은 다른 언어로 일하기를 고집하고 아무도 서로 상호 작용하는 방법을 알아낼 수 없으므로 어느 누구도 자신이 좋아하는 언어를 부과 언어로 바꾸어 어떻게 할 수 있는지 알아낼 수 있습니다. 그들은 원한다.

내가 그것을 유지해야 할 때까지는 괜찮습니다. 어느 시점에서 당신은 모두 죽을 수 있습니다.

안티 패턴입니까? 안돼. 우리가 이전 언어의 단점에 작별 인사를하지 않고 이전 언어의 코드를 생성하는 것이 얼마나 많은 새로운 언어가 시작되는지에 따라 많은 언어가 존재하지 않을 것입니다.

그것은 내가 참을 수없는 반 변환 된 Frankenstein 괴물 패치 워크에 남겨진 코드베이스입니다. 생성 된 코드는 만질 수없는 코드입니다. 나는 만질 수없는 코드를 보는 것이 싫어. 그러나 사람들은 계속 확인하고 있습니다. 왜? 실행 파일을 체크인하고있을 수도 있습니다.

이제 나는 뛰고있다. 내 요점은 우리 모두 “코드 생성”입니다. 생성 된 코드를 소스 코드처럼 취급하여 나를 미치게 만들 때입니다. 소스 코드가 소스 코드가 아닌 것처럼 보이게하십시오.


답변

소스 코드를 생성하는 이유

내 경력에서 작업해야했던 코드 생성기의 가장 빈번한 사용 사례는 생성기였습니다.

  • 어떤 종류의 데이터 모델이나 데이터베이스 스키마에 대한 높은 수준의 메타 설명을 입력으로 사용했습니다 (관계형 스키마 또는 XML 스키마)

  • 출력으로서 데이터 액세스 클래스를위한 보일러 플레이트 CRUD 코드 및 해당 SQL 또는 문서와 같은 추가 항목을 생성했습니다.

여기서 짧은 이점은 짧은 입력 사양의 한 줄에서 5-10 줄의 디버그 가능하고 형식이 안전하며 버그가없는 (코드 생성기 출력이 성숙하다고 가정) 코드를 직접 구현하고 유지 관리해야한다는 점입니다. 이것이 유지 관리 및 진화 노력을 얼마나 줄일 수 있는지 상상할 수 있습니다.

당신의 첫 질문에 답하겠습니다

소스 코드 생성은 안티 패턴입니까

아니요, 소스 코드 생성 자체는 아니지만 실제로 몇 가지 함정이 있습니다. Pragmatic Programmer에 명시된 바와 같이 , 이해하기 어려운 코드를 생성 할 때 코드 생성기를 사용하지 않아야합니다 . 그렇지 않으면이 코드를 사용하거나 디버깅하려는 노력이 증가하면 코드를 수동으로 작성하지 않아도 절약되는 노력보다 쉽게 ​​수행 할 수 있습니다.

또한 재생성으로 인해 수동 변경 사항을 덮어 쓰지 않는 방식으로 생성 된 코드 부분을 수동으로 작성된 코드와 물리적으로 분리하는 것이 좋습니다. 그러나 나는 또한 언어 Y로 유지 보수하려는 의도로 구식 X로 작성된 일부 코드를 더 현대적인 언어 Y로 마이그레이션하는 상황을 두 번 이상 처리했습니다. 일회성 코드 생성의 경우.


답변

왜 소스 코드를 생성합니까?

생성 된 (빌드 타임에, 체크인되지 않은) 코드에 대한 두 가지 유스 케이스가 발생했습니다.

  1. 이러한 것들을 지정하기 위해 만들어진 언어에서 getter / setter, toString, equals 및 hashCode와 같은 상용구 코드를 자동으로 생성합니다 (예 : Java 용 lombok 프로젝트)
  2. 일부 인터페이스 사양 (REST, SOAP 등)에서 DTO 유형 클래스를 자동으로 생성 한 후 기본 코드에서 사용합니다. 이것은 언어 브릿지 문제와 비슷하지만 생성 된 클래스없이 동일한 것을 구현하려고 시도하는 것보다 유형 처리가 더 깨끗하고 간단합니다.

답변

Sussmann은 그의 고전적인 “컴퓨터 프로그램의 구조와 해석”에서 주로 코드-데이터 이중성에 대해 그런 것들에 대해 매우 흥미로웠다.

나를 위해 adhoc 코드 생성의 주요 용도는 사용 가능한 컴파일러를 사용하여 일부 도메인 특정 언어를 프로그램에 연결할 수있는 언어로 변환하는 것입니다. BNF를 생각하고, ASN1을 생각하고 (사실, 그렇지 않습니다, 추악합니다), 데이터 사전 스프레드 시트를 생각하십시오.

사소한 도메인 특정 언어는 시간을 크게 절약 할 수 있으며 표준 언어 도구로 컴파일 할 수있는 것을 출력하는 것은 그러한 것을 만들 때 갈 수있는 방법입니다. 자동 생성 또는 쓰기 또는 BNF?

텍스트를 출력 한 다음 일부 시스템 컴파일러에 공급하면 모든 컴파일러 최적화 및 시스템 특정 구성을 생각하지 않아도됩니다.

컴파일러 입력 언어를 다른 중간 표현으로 효과적으로 사용하고 있습니다. 문제는 무엇입니까? 텍스트 파일은 본질적으로 소스 코드가 아니며 컴파일러의 IR 일 수 있으며 C 또는 C ++ 또는 Java처럼 보이면 누가 신경 쓰나요?

이제 당신이 장난감 언어 파서의 OUTPUT을 편집 할 수 있다고 생각 하지 않는다면 , 다음에 누군가가 입력 언어 파일을 편집하고 다시 작성할 때 분명히 실망 할 것입니다. 답은 자동 생성 IR을 저장소에 커밋하지 않는 것입니다. 당신의 툴체인에 의해 생성됩니다 (그리고 당신의 개발자 그룹에 그런 사람들을 두지 마십시오, 그들은 일반적으로 마케팅에서 더 행복합니다).

때로는 사양의 일부를 자동으로 코드로 변환 할 수있는 형태로 얻을 수 있고 일반적으로 훨씬 적은 형태로 표현할 수 있다는 사실을 표현하기 때문에 언어 표현력의 실패가 아닙니다. 버그 및 유지 관리가 훨씬 쉬워집니다. 테스트 및 구성 담당자에게 스프레드 시트를 제공 할 수 있고 데이터를 가져 와서 ECU에서 플래시를위한 완전한 16 진수 파일을 추출하는 도구를 실행할 수 있다면 누군가 수동으로 번역하는 것보다 시간을 절약 할 수 있습니다 오늘의 언어로 된 상수 세트에 대한 최신 설정

Simulink에서 모델을 빌드 한 다음 RTW로 C를 생성 한 다음 어떤 툴이든지 적절한 대상으로 컴파일하기 위해 컴파일하는 것과 마찬가지로 중간 C는 읽을 수 없습니다. 높은 수준의 Matlab RTW는 C의 하위 집합 만 알아야하며 C 컴파일러는 플랫폼 세부 정보를 처리합니다. RTW 스크립트에 버그가있는 경우에만 인간이 생성 된 C를 통해 그 로브해야 할 때가 있으며, 이러한 종류의 작업은 명목상 사람이 읽을 수있는 IR로 디버깅하고 이진 구문 분석 트리만으로 훨씬 쉽게 디버깅 할 수 있습니다.

물론 바이트 코드 또는 실행 코드를 출력하기 위해 그러한 것들을 작성할 수는 있지만 왜 그렇게 할 것입니까? 우리는 IR을 그런 것들로 변환하는 도구를 얻었습니다.


답변

실용 답변 : 코드 생성이 필요하고 유용합니까? 독점적 인 코드베이스에 진정으로 매우 유용하고 필요한 것을 제공합니까, 아니면 차선책의 결과에 대한 지적 부담을 높이는 다른 방법을 만드는 것처럼 보입니까?

좋아, 나는 코드도 데이터라는 것을 안다. 내가 이해하지 못하는 것은 왜 코드를 생성하는 것입니까? 파라미터를 받아 들여서 작동 할 수있는 함수로 만들어 보지 않겠습니까?

이 질문을해야하는데 명확한 대답이 없다면 아마도 코드 생성이 불필요 할뿐 아니라 코드베이스에 이국주의와 많은 지적 오버 헤드를주는 것입니다.

한편 OpenShadingLanguage와 같은 것을 사용하는 경우 :
https://github.com/imageworks/OpenShadingLanguage

… 그러한 질문은 인상적인 결과에 의해 즉시 답변되기 때문에 제기 될 필요가 없습니다.

OSL은 LLVM 컴파일러 프레임 워크를 사용하여 셰이더 네트워크를 즉시 (시간 또는 “JIT”) 기계 코드로 변환하고, 그 과정에서 셰이더 매개 변수 및 기타 런타임 값에 대한 전체 지식을 바탕으로 셰이더와 네트워크를 크게 최적화합니다. 쉐이더가 소스 코드에서 컴파일 될 때 알려졌습니다. 결과적으로 OSL 쉐이딩 네트워크가 C에서 수작업으로 제작 한 동등한 쉐이더보다 25 % 더 빠르게 실행되는 것을 볼 수 있습니다! (이것은 이전 셰이더가 렌더러에서 작동 한 방식입니다.)

이 경우 코드 생성기의 존재 여부를 의심 할 필요가 없습니다. 이 유형의 VFX 도메인에서 작업하는 경우 일반적으로 “종료하고 내 돈을 가져라!” 또는 “와우, 우리도 이와 같은 것을 만들어야합니다.”