정적 분석 유형에 대한 대안이 있습니까?


18

프로그래밍 언어의 정적 타이핑은 컴파일 타임에 특정 보증을 시행하는 데 도움이 될 수 있지만 유형이이 작업을위한 유일한 도구입니까? 불변량을 지정하는 다른 방법이 있습니까?

예를 들어, 언어 또는 환경은 배열 길이 또는 입력과 함수 간의 관계에 대한 보증을 강화하는 데 도움이 될 수 있습니다. 나는 타입 시스템 외부에서 이와 같은 것을 들어 본 적이 없다.

내가 궁금해했던 것은 정적 분석을 수행하는 비 선언적 방법이 있는지 여부입니다 (유형은 대부분 선언적입니다 ).

답변:


24

정적 유형 시스템은 일종의 정적 분석이지만 일반적으로 유형 시스템으로 인코딩되지 않은 많은 정적 분석이 있습니다. 예를 들면 다음과 같습니다.

  • 모델 검사 는 가능한 모든 스레드 인터리빙에서 프로그램이 올바르게 작동 함을 증명할 수있는 동시 시스템에 대한 분석 및 검증 기술입니다.

  • 데이터 흐름 분석 은 변수의 가능한 값에 대한 정보를 수집하여 일부 계산이 중복되는지 또는 일부 오류가 고려되지 않았는지 확인할 수 있습니다.

  • 추상 해석 은 일반적으로 분석이 종료되도록 보장하는 방식으로 프로그램의 효과를 보수적으로 모델링합니다. 형식 검사기는 추상 해석기와 유사한 방식으로 구현 될 수 있습니다.

  • 분리 로직 은 프로그램 상태에 대해 추론 하고 널 포인터 역 참조, 유효하지 않은 상태 및 리소스 누수와 같은 문제를 식별하는 데 사용할 수 있는 프로그램 로직 (예 : 추론 분석기 에서 사용 )입니다.

  • 계약 기반 프로그래밍 은 전제 조건, 사후 조건, 부작용 및 변형을 지정하는 수단입니다. Ada 는 계약을 기본적으로 지원하며 일부 계약을 정적으로 확인할 수 있습니다.

최적화 컴파일러는 최적화 중에 사용할 SSA, 인라인 비용 추정, 명령어 쌍 정보 등과 같은 중간 데이터 구조를 구축하기 위해 많은 소규모 분석을 수행합니다.

선언적이지 않은 정적 분석의 또 다른 예는 Hack typechecker 에서 찾을 수 있는데, 일반적인 제어 흐름 구성은 변수의 유형을 세분화 할 수 있습니다.

$x = get_value();
if ($x !== null) {
    $x->method();    // Typechecks because $x is known to be non-null.
} else {
    $x->method();    // Does not typecheck.
}

그리고 타입 시스템의 땅에서, "리파이닝 (refining)"에 대해 말하면, 리파이닝 타입 ( LiquidHaskell에 사용 된 ) 리파이닝 타입은 "리파이닝 된"타입의 인스턴스를 위해 보장되는 술어와 페어 타입입니다. 그리고 종속 유형 은 더 나아가 유형 이 값에 종속되도록합니다. 의존적 타이핑의 "hello world"는 일반적으로 배열 연결 함수입니다.

(++) : (a : Type) -> (m n : Nat) -> Vec a m -> Vec a n -> Vec a (m + n)

여기서, ++두 가지 유형의 피연산자 얻어 Vec a mVec a n요소 형, 인 벡터 a과 길이 mn자연수를 각각 ( Nat). 길이가 인 요소 유형이 같은 벡터를 반환합니다 m + n. 그리고이 함수는 m및 의 특정 값을 모른 채이 제약 조건을 추상적으로 증명 n하므로 벡터의 길이는 동적 일 수 있습니다.


타입 시스템이란 무엇입니까? 나는 실제로 모른다는 것을 알고 있습니다. 위키 백과에 대한 정의는 순환 적입니다 : en.wikipedia.org/wiki/Type_system
Max Heiber

1
@mheiber : 정적 타입 시스템은 정적 분석은 단순히 그 돌린다 유형 (예를 들어, int, int -> int, forall a. a -> a)을 이용 (예를 들어 0, (+ 1), \x -> x). 다른 분석은 부작용 ( pure, io), 가시성 ( public, private) 또는 상태 ( open, closed) 와 같이 데이터 유형과 관련이없는 다른 속성을 나타낼 수 있습니다 . 실제로 이러한 속성 중 다수는 유형 확인 / 유추와 동일한 구현에서 확인할 수 있으므로 구분이 명확하지 않습니다.
Jon Purdy

4

@ JonPurdy의 대답이 더 좋지만 몇 가지 예를 더 추가하고 싶습니다.

분명한:

  • 구문 검사

  • 보푸라기

명백한

  • Rust를 사용하면 프로그래머가 "바인딩"을 변경할 수 있는지 여부 를 지정 하고 이러한 제약 조건을 적용 할 수 있습니다.

  • 이것은 일종의 관련입니다. 일부 언어는 일부 코드가 컴파일 타임에 실행될 수 있도록합니다. 즉, 런타임 오류가되는 많은 것들이 컴파일 타임에 잡힐 수 있습니다. 일부 예는 pragma 로 표시된 매크로 및 Nim 언어 프로 시저 입니다.compileTime

  • 논리 프로그래밍 은 기본적으로 어설 션을 제공하여 프로그램을 작성합니다.

반 정적 타이핑 :

  • Facebook의 흐름을 사용하면 동적 입력과 정적 입력을 혼합 할 수 있습니다. 아이디어는 동적 코드조차도 암시 적으로 입력된다는 것입니다. Flow를 사용하면 함수에 주석을 달지 않아도 가능한 유형 오류를 감지하기 위해 코드를 실행하는 서버를 실행할 수 있습니다.

1

타입 분석은 그다지 의미가 없습니다.

Agda 는 ML 언어 (예 : Ocaml ) 와는 매우 다른 (계산이 훨씬 어려운) Turing-complete 유형 시스템을 사용하는 것으로 알려져 있습니다 .


Agda는 "Turing-complete type system"을 갖지 않으며 "Turing-complete term system"을 갖지 않기 위해 많은 노력을 기울입니다.
user833970
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.