동적 프로그래밍 언어

Dynamic programming language

컴퓨터 과학에서 동적 프로그래밍 언어(dynamic programming language)는 고급 프로그래밍 언어의 한 종류로, 런타임에 정적 프로그래밍 언어가 컴파일 중에 수행하는 많은 일반적인 프로그래밍 동작을 실행합니다.이러한 동작에는 프로그램 확장, 새 코드 추가, 개체 및 정의 확장 또는 유형 시스템 수정 등이 포함될 수 있습니다.유사한 동작은 거의 모든 언어로 에뮬레이트할 수 있지만, 난이도, 복잡성 및 성능 비용은 다양합니다.다이나믹 언어는 이러한 동작을 사용하기 위한 직접적인 도구를 제공합니다.이러한 기능의 대부분은 리스프 프로그래밍 언어의 네이티브 기능으로 처음 구현되었습니다.

대부분의 동적 언어도 동적으로 입력되지만 모든 언어가 입력되는 것은 아닙니다.동적 언어는 스크립팅 언어라고 불리는 경우가 많지만(항상 그렇지는 않습니다), 가장 좁은 의미에서 스크립팅 언어는 특정 런타임 환경에 고유한 언어를 가리킵니다.

실행

평가

일부 동적 언어는 평가 기능을 제공합니다.이 함수는 언어의 코드를 포함하는 문자열 또는 추상 구문 트리를 가져와 실행합니다.이 코드가 식을 나타내는 경우 결과 값이 반환됩니다.Erik Meijer와 Peter Drayton은 eval에 의해 제공되는 런타임 코드 생성과 공유 라이브러리에 의해 제공되는 동적 로드를 구별하고, eval은 많은 경우에 단순히 고차 함수(함수를 문자열로 전달함) 또는 역직렬화([1]deserialization)를 구현하기 위해 사용된다고 경고한다.

오브젝트 런타임 변경

유형 또는 객체 시스템은 일반적으로 런타임 중에 동적 언어로 수정할 수 있습니다.즉, 런타임 정의에서 새 개체를 생성하거나 기존 유형 또는 개체의 혼합을 기반으로 생성할 수 있습니다.는 상속 또는 유형 트리의 변경과 함께 기존 유형의 동작 방식(특히 메서드의 호출과 관련하여)을 변경하는 것을 의미할 수도 있습니다.

유형 추론

많은 동적 언어들이 동적 유형 시스템과 함께 제공되기 때문에, 내부 해석에 대한 값에 기초한 유형의 런타임 추론은 공통 작업을 나타낸다.값 유형은 해석 내내 변경될 수 있으므로 원자 연산을 수행할 때 정기적으로 사용됩니다.

가변 메모리 할당

정적 프로그래밍 언어는 (아마도 간접적으로) 개발자가 컴파일 전에 사용된 메모리의 크기를 정의해야 합니다(포인터 로직으로 작업하지 않는 한).오브젝트 런타임 변경과 일관되게 동적 언어는 암묵적으로 프로그램 개개의 조작에 근거해 메모리를 할당(재할당)할 필요가 있습니다.

반사

리플렉션(reflection)은 많은 동적 언어에서 흔히 볼 수 있으며 일반적으로 범용 또는 다형 데이터의 유형과 메타데이터를 분석합니다.그러나 Lisp가 S 표현식 분석에 제공하는 기능과 같이 프로그램 코드의 완전한 평가와 데이터 수정을 포함할 수도 있습니다.

매크로

제한된 수의 동적 프로그래밍 언어가 코드 인스펙션(클래스, 함수 및 키워드를 검사하여 클래스, 함수 및 키워드가 무엇인지, 무엇을 알고 있는지 알 수 있는 기능)과 매크로라고 불리는 기능을 결합한 기능을 제공합니다.매크로라는 용어를 알고 있는 대부분의 프로그래머들은 C 또는 C++에서 그것들을 접해 왔습니다.C+는 언어의 작은 서브셋에 내장된 정적 기능으로 프로그램 텍스트에서만 문자열 치환을 수행할 수 있습니다.그러나 동적 언어에서는 컴파일러의 내부 기능에 대한 액세스와 인터프리터, 가상 머신 또는 런타임에 대한 완전한 액세스를 제공하여 코드를 최적화하거나 언어의 구문이나 문법을 수정할 수 있는 언어와 유사한 구조를 정의할 수 있습니다.

어셈블리, C, C++, 초기 Java 및 Fortran은 일반적으로 이 [clarification needed]범주에 포함되지 않습니다.

코드 예시

다음으로 Common LispCommon Lisp Object System(CLOS; 공통 리스프 오브젝트 시스템) 언어를 사용한 다이내믹 기능의 예를 나타냅니다.

런타임 및 지연 바인딩 시 코드 계산

이 예에서는 함수를 런타임에 계산된 소스 코드에서 변경하는 방법을 보여 줍니다.

; 소스 코드는 변수에 데이터로 저장됩니다. CL 사용자 > (디파라미터 *best-first-first* '(람다 (x) (* x x 2.5))) *BEST-GUESS-FORMULA*  함수는 코드에서 생성되어 런타임에 컴파일됩니다.함수는 best-interminal이라는 이름으로 사용할 수 있습니다. CL 사용자 >  (컴파일하다 '베스트 페어' *best-first-first*) #<기능 15 40600152F4 >  ; 함수를 호출할 수 있습니다. CL 사용자 > (최강의 10.3) 265.225  ; 실행 시 소스 코드가 개선될 수 있습니다. CL 사용자 > (설정 *best-first-first* `(람다 (x) ,(목록. '실행하지 않다 (셋째 *best-first-first*)))) (램다 (X) (SQRT (* X X 2.5)))  ; 함수의 새 버전을 컴파일 중입니다. CL 사용자 > (컴파일하다 '베스트 페어' *best-first-first*) #<기능 16 406000085C>  ; 다음 콜은 레이트바인딩의 기능인 새로운 기능을 호출합니다. CL 사용자 > (최강의 10.3) 16.28573 

오브젝트 런타임 변경

다음 예시는 클래스가 변경되었을 때 기존 인스턴스를 변경하여 새 슬롯을 포함하는 방법과 기존 메서드를 새 버전으로 교체하는 방법을 보여 줍니다.

; 인물 클래스.그 사람은 이름이 있어요. CL 사용자 > (디클래스 사람인 () ((이름. : initarg : 이름))) #<표준 클래스> 사람인 4020081FB3>  ; 클래스 인물의 오브젝트에 대한 커스텀 인쇄 방법 CL 사용자 > (디프로덕트 프린트 오브젝트 ((p 사람인) 개울.)             (인쇄 가능한 오브젝트 (p 개울. : 타입 t)               (포맷 개울. "~a" (슬롯 값 p 이름)))) #<표준> 방법 프린트 오브젝트 없음 (사람인 T) 4020066E5B>  ; 1가지 예시의 인물 인스턴스 CL 사용자 > (설정 *사람-1* (제조법 '사람 : 이름 에바 루아토르)) #<인물 에바 Luator >  ; 클래스 인원은 두 번째 슬롯을 받는다.슬롯명과 경과시간이 표시됩니다. CL 사용자 > (디클래스 사람인 () ((이름. : initarg : 이름) (나이 : initarg : 연령 : 초기화 : 개요))) #<표준 클래스> 사람인 4220333E23>  ; 오브젝트를 인쇄하는 메서드를 갱신합니다. CL 사용자 > (디프로덕트 프린트 오브젝트 ((p 사람인) 개울.)             (인쇄 가능한 오브젝트 (p 개울. : 타입 t)               (포맷 개울. "~ 나이:~" (슬롯 값 p 이름) (슬롯 값 p 나이)))) #<표준> 방법 프린트 오브젝트 없음 (사람인 T) 402022ADE3>  ; 기존 오브젝트가 변경되어 슬롯이 추가되어 새로운 인쇄 방법이 추가되었습니다. CL 사용자 > *사람-1* #<인물 에바 루아토르 경과시간: 불명>  ; 인스턴스의 새로운 에이징 슬롯을 설정할 수 있습니다. CL 사용자 > (설정 (슬롯 값 *사람-1* 나이) 25) 25  ; 객체가 갱신되었습니다. CL 사용자 > *사람-1* #<인물 에바 루아토르 경과시간: 25 > 

인스턴스 클래스를 기반으로 런타임에 코드 어셈블리

다음 예제에서는 클래스 사용자가 새로운 슈퍼클래스를 받습니다.인쇄 방법은 몇 가지 방법을 조합하여 효과적인 방법으로 다시 정의됩니다.유효한 메서드는 인수의 클래스와 사용 가능한 실행 시 적용 가능한 메서드에 따라 조합됩니다.

; 학급 사람 CL 사용자 > (디클래스 사람인 () ((이름. : initarg : 이름))) #<표준 클래스> 사람인 4220333E23>  ; 사람은 이름만 출력한다. CL 사용자 > (디프로덕트 프린트 오브젝트 ((p 사람인) 개울.)             (인쇄 가능한 오브젝트 (p 개울. : 타입 t)               (포맷 개울. "~a" (슬롯 값 p 이름)))) #<표준> 방법 프린트 오브젝트 없음 (사람인 T) 40200605AB>  ; 인물 사례 CL 사용자 > (디파라미터 *사람-1* (제조법 '사람 : 이름 에바 루아토르)) *Person-1*  ; 사용자 인스턴스 표시 CL 사용자 > *사람-1* #<인물 에바 Luator >  ; 현재 인쇄 방법을 확장 가능하도록 재정의하고 있습니다. ; around 메서드는 인쇄 방식의 콘텍스트를 생성하고 다음 메서드를 호출합니다. CL 사용자 > (디프로덕트 프린트 오브젝트 : 개요 ((p 사람인) 개울.)             (인쇄 가능한 오브젝트 (p 개울. : 타입 t)               (다음 번에 호출하다))) #<표준> 방법 프린트 오브젝트 (: 어라운드) (사람인 T) 4020263743>  ; 프라이머리 메서드는 이름을 출력합니다. CL 사용자 > (디프로덕트 프린트 오브젝트 ((p 사람인) 개울.)             (포맷 개울. "~a" (슬롯 값 p 이름))) #<표준> 방법 프린트 오브젝트 없음 (사람인 T) 40202646BB>  ; 새로운 클래스 id-classin이 ID를 제공합니다. CL 사용자 > (디클래스 id 로그인 () ((아이디 : initarg : id))) #<표준 클래스> 아이디믹스 422034A7AB>  ; print method는 id 슬롯의 값만 출력합니다. CL 사용자 > (디프로덕트 프린트 오브젝트 : 이후 ((물건 id 로그인) 개울.)           (포맷 개울. "ID: ~a" (슬롯 값 물건 아이디))) #<표준> 방법 프린트 오브젝트 (: 이후) (아이디믹스 T) 4020278E33>  ; 이제 mixin id-in을 포함하도록 클래스 사용자를 재정의합니다. CL 사용자 241 > (디클래스 사람인 (id 로그인) ((이름. : initarg : 이름))) #<표준 클래스> 사람인 4220333E23>  ; 기존 인스턴스 *person-1*에 새로운 슬롯이 추가되어 42로 설정됩니다. CL 사용자 242 > (설정 (슬롯 값 *사람-1* 아이디) 42) 42  ; 오브젝트를 다시 표시합니다.print-object 함수는 효과적인 메서드를 갖게 되었습니다.이 메서드는 어라운드 메서드, 프라이머리 메서드 및 애프터 메서드의 3가지 메서드를 호출합니다. CL 사용자 243 > *사람-1* #<인물 에바 루아토르 아이디: 42 > 

인기 있는 동적 프로그래밍 언어로는 JavaScript, Python, Ruby, PHP, LuaPerl있습니다.일반적으로 다음 언어는 동적 언어로 간주됩니다.

「 」를 참조해 주세요.

레퍼런스

  1. ^ Meijer, Erik and Peter Drayton (2005), Static Typing Where Possible, Dynamic Typing When Needed: The End of the Cold War Between Programming Languages (PDF), Microsoft Corporation, CiteSeerX 10.1.1.69.5966
  2. ^ 24장 동적 언어 지원Static.springsource.org 를 참조해 주세요.2013-07-17에 회수.
  3. ^ <: CS1 maint: 타이틀로서의 아카이브 카피(링크)

추가 정보

외부 링크

(많은 경우 스크립트 언어라는 용어를 사용합니다.)