정적으로 입력되는 언어와 동적으로 입력되는 언어의 차이점은 무엇입니까?
새로운 프로그래밍 언어가 동적으로 입력된다는 말을 많이 듣습니다.하지만 언어가 동적으로 입력되는 것과 정적으로 입력되는 것이 실제로 무엇을 의미합니까?
정적으로 입력 된 언어
컴파일 타임에 변수 유형이 알려진 경우 언어는 정적으로 유형이 지정됩니다. 일부 언어의 경우 이는 프로그래머가 각 변수의 유형 (예 : Java, C, C ++)을 지정해야 함을 의미합니다. 다른 언어는 어떤 형태의 유형 추론 , 변수 유형을 추론하는 유형 시스템의 기능을 제공합니다 (예 : OCaml, Haskell, Scala, Kotlin).
여기에서 가장 큰 장점은 모든 종류의 검사가 컴파일러에 의해 수행 될 수 있으므로 매우 초기 단계에서 사소한 버그가 많이 발견된다는 것입니다.
예 : C, C ++, Java, Rust, Go, Scala
동적으로 입력 된 언어
유형이 이름이 지정된 변수 / 필드 / 등이 아니라 런타임 값과 연관되는 경우 언어는 동적으로 유형이 지정됩니다. 이것은 프로그래머로서 매번 유형을 지정할 필요가 없기 때문에 조금 더 빨리 작성할 수 있음을 의미합니다 ( 유형 추론 과 함께 정적으로 유형이 지정된 언어를 사용하지 않는 한 ).
예 : Perl, Ruby, Python, PHP, JavaScript
어쨌든 정적 유형 검사를 수행하는 컴파일러가 없기 때문에 대부분의 스크립팅 언어에는이 기능이 있지만 인터프리터가 변수 유형을 잘못 해석하여 버그를 검색 할 수 있습니다. 운 좋게도 스크립트는 작기 때문에 버그는 숨길 곳이 많지 않습니다.
대부분의 동적 유형 언어에서는 유형 정보를 제공 할 수 있지만 필수는 아닙니다. 현재 개발중인 언어 중 하나 인 Rascal 은 함수 내에서 동적 타이핑을 허용하지만 함수 시그니처에 대해 정적 타이핑을 적용하는 하이브리드 접근 방식을 취합니다.
정적으로 형식화 된 프로그래밍 언어는 런타임이 아닌 컴파일 타임에 형식 검사 (즉 형식의 제약 조건을 확인하고 적용하는 프로세스) 를 수행합니다 .
동적 형식의 프로그래밍 언어는 컴파일 타임 이 아닌 런타임에 형식 검사를 수행 합니다 .
다음은 Python (동적 형식 지정)과 Go (정적 형식 지정)가 형식 오류를 처리하는 방법을 대조하는 예입니다.
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
Python은 런타임에 유형 검사를 수행하므로 다음과 같습니다.
silly(2)
완벽하게 잘 실행되고 예상되는 출력을 생성합니다 Hi
. 문제가있는 줄이 맞을 때만 오류가 발생합니다.
silly(-1)
생산
TypeError: unsupported operand type(s) for +: 'int' and 'str'
관련 라인이 실제로 실행 되었기 때문입니다.
반면에 Go는 컴파일 타임에 유형 검사를 수행합니다.
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
위의 내용은 다음 오류와 함께 컴파일되지 않습니다.
invalid operation: "3" + 5 (mismatched types string and int)
간단히 말해서, 정적으로 입력 된 언어에서 변수의 유형은 static입니다 . 즉, 일단 변수를 유형으로 설정하면 변경할 수 없습니다. 입력은 참조하는 값이 아닌 변수와 연관되기 때문입니다.
예를 들어 Java에서 :
String str = "Hello"; //variable str statically typed as string
str = 5; //would throw an error since str is supposed to be a string only
반면에, 동적으로 입력 된 언어에서 변수의 유형은 동적입니다 . 즉, 변수를 유형으로 설정 한 후 변경할 수 있습니다. 입력은 변수 자체가 아니라 가정하는 값과 연관되기 때문입니다.
예를 들어 Python에서 :
str = "Hello" # variable str is linked to a string value
str = 5 # now it is linked to an integer value; perfectly OK
따라서 동적 유형 언어의 변수 를 유형 값에 대한 일반적인 포인터 로 생각하는 것이 가장 좋습니다 .
요약하면 type 은 언어 자체가 아닌 언어의 변수를 설명하거나 설명해야합니다. 동적으로 유형이 지정된 변수 IMHO가 있는 언어 보다 정적으로 유형이 지정된 변수가있는 언어 로 더 잘 사용되었을 수 있습니다 .
정적으로 형식화 된 언어는 일반적으로 컴파일 된 언어이므로 컴파일러는 형식을 확인합니다 (나중에 런타임에 형식을 변경할 수 없으므로 완벽하게 이해됩니까?).
동적으로 유형이 지정된 언어는 일반적으로 해석되므로 유형 검사 (있는 경우)가 사용될 때 런타임에 발생합니다. 이것은 물론 약간의 성능 비용이 발생하고 동적 언어 (예 : python, ruby, php)가 입력 된 언어 (java, c # 등)만큼 확장되지 않는 이유 중 하나입니다. 다른 관점에서 보면 정적으로 형식화 된 언어는 시작 비용이 더 많이 듭니다. 일반적으로 더 많은 코드를 작성하고 더 어려운 코드를 작성하게합니다. 그러나 그것은 나중에 지불됩니다.
좋은 점은 양쪽이 다른 쪽에서 기능을 차용한다는 것입니다. 형식화 된 언어는 더 많은 동적 기능 (예 : C #의 제네릭 및 동적 라이브러리)을 통합하고, 동적 언어에는 더 많은 형식 검사 (예 : Python의 형식 주석 또는 일반적으로 언어의 핵심이 아니고 사용할 수있는 PHP의 HACK 변형)가 포함됩니다. 수요.
기술 선택과 관련하여 어느 쪽도 다른 쪽보다 본질적으로 우월합니다. 더 많은 제어를 원하든 유연성을 원하든 선호하는 문제 일뿐입니다. 작업에 적합한 도구를 선택하고 전환을 고려하기 전에 반대 측면에서 사용할 수있는 도구를 확인하십시오.
http://en.wikipedia.org/wiki/Type_system
정적 타이핑
프로그래밍 언어는 런타임이 아닌 컴파일 타임에 유형 검사를 수행 할 때 정적 유형을 사용한다고합니다. 정적 유형에서 유형은 값이 아닌 변수와 연관됩니다. 정적으로 유형이 지정된 언어에는 Ada, C, C ++, C #, JADE, Java, Fortran, Haskell, ML, Pascal, Perl (구별 스칼라, 배열, 해시 및 서브 루틴과 관련하여) 및 Scala가 포함됩니다. 정적 유형 지정은 제한된 형태의 프로그램 검증입니다 (유형 안전성 참조). 따라서 개발주기 초기에 많은 유형 오류를 포착 할 수 있습니다. 정적 유형 검사기는 컴파일 시간에 확인할 수있는 유형 정보 만 평가하지만 검사 된 조건이 프로그램의 가능한 모든 실행에 대해 유지되는지 확인할 수 있으므로 프로그램이 실행될 때마다 유형 검사를 반복 할 필요가 없습니다.
컴파일하는 동안 형식 정보를 평가하므로 런타임에만 사용할 수있는 형식 정보가 없기 때문에 정적 형식 검사기는 보수적입니다. 그들은 런타임에 잘 작동 할 수 있지만 정적으로 올바른 형식으로 결정될 수없는 일부 프로그램을 거부합니다. 예를 들어 표현식이 런타임에 항상 true로 평가 되더라도 코드를 포함하는 프로그램은
if <complex test> then 42 else <type error>
정적 분석에서는 else 분기가 사용되지 않는다는 것을 결정할 수 없기 때문에 잘못된 유형으로 거부됩니다. [1] 정적 유형 검사기의 보수적 인 동작은 가끔 false로 평가 될 때 유리합니다. 정적 유형 검사기는 거의 사용되지 않는 코드 경로에서 유형 오류를 감지 할 수 있습니다. 정적 유형 검사가 없으면 100 % 코드 검사를 사용하는 코드 검사에서도 이러한 유형 오류를 찾지 못할 수 있습니다. 코드 커버리지 테스트는 값이 생성되는 모든 위치와 특정 값이 사용되는 모든 위치의 조합을 고려해야하기 때문에 이러한 유형 오류를 감지하지 못할 수 있습니다.
가장 널리 사용되는 정적으로 형식화 된 언어는 형식적으로 안전하지 않습니다. 프로그래밍 언어 사양에 "허점"이있어 프로그래머가 정적 유형 검사기에 의해 수행되는 확인을 우회하는 코드를 작성할 수 있으므로보다 광범위한 문제를 해결할 수 있습니다. 예를 들어, Java 및 대부분의 C 스타일 언어에는 유형 punning이 있고 Haskell에는 unsafePerformIO와 같은 기능이 있습니다. 이러한 작업은 프로그램이 실행될 때 값을 잘못 입력하여 원하지 않는 동작을 일으킬 수 있다는 점에서 런타임시 안전하지 않을 수 있습니다.
동적 타이핑
A programming language is said to be dynamically typed, or just 'dynamic', when the majority of its type checking is performed at run-time as opposed to at compile-time. In dynamic typing, types are associated with values not variables. Dynamically typed languages include Groovy, JavaScript, Lisp, Lua, Objective-C, Perl (with respect to user-defined types but not built-in types), PHP, Prolog, Python, Ruby, Smalltalk and Tcl. Compared to static typing, dynamic typing can be more flexible (e.g. by allowing programs to generate types and functionality based on run-time data), though at the expense of fewer a priori guarantees. This is because a dynamically typed language accepts and attempts to execute some programs which may be ruled as invalid by a static type checker.
Dynamic typing may result in runtime type errors—that is, at runtime, a value may have an unexpected type, and an operation nonsensical for that type is applied. This operation may occur long after the place where the programming mistake was made—that is, the place where the wrong type of data passed into a place it should not have. This makes the bug difficult to locate.
Dynamically typed language systems, compared to their statically typed cousins, make fewer "compile-time" checks on the source code (but will check, for example, that the program is syntactically correct). Run-time checks can potentially be more sophisticated, since they can use dynamic information as well as any information that was present during compilation. On the other hand, runtime checks only assert that conditions hold in a particular execution of the program, and these checks are repeated for every execution of the program.
Development in dynamically typed languages is often supported by programming practices such as unit testing. Testing is a key practice in professional software development, and is particularly important in dynamically typed languages. In practice, the testing done to ensure correct program operation can detect a much wider range of errors than static type-checking, but conversely cannot search as comprehensively for the errors that both testing and static type checking are able to detect. Testing can be incorporated into the software build cycle, in which case it can be thought of as a "compile-time" check, in that the program user will not have to manually run such tests.
References
- Pierce, Benjamin (2002). Types and Programming Languages. MIT Press. ISBN 0-262-16209-1.
The terminology "dynamically typed" is unfortunately misleading. All languages are statically typed, and types are properties of expressions (not of values as some think). However, some languages have only one type. These are called uni-typed languages. One example of such a language is the untyped lambda calculus.
In the untyped lambda calculus, all terms are lambda terms, and the only operation that can be performed on a term is applying it to another term. Hence all operations always result in either infinite recursion or a lambda term, but never signal an error.
However, were we to augment the untyped lambda calculus with primitive numbers and arithmetic operations, then we could perform nonsensical operations, such adding two lambda terms together: (λx.x) + (λy.y)
. One could argue that the only sane thing to do is to signal an error when this happens, but to be able to do this, each value has to be tagged with an indicator that indicates whether the term is a lambda term or a number. The addition operator will then check that indeed both arguments are tagged as numbers, and if they aren't, signal an error. Note that these tags are not types, because types are properties of programs, not of values produced by those programs.
A uni-typed language that does this is called dynamically typed.
Languages such as JavaScript, Python, and Ruby are all uni-typed. Again, the typeof
operator in JavaScript and the type
function in Python have misleading names; they return the tags associated with the operands, not their types. Similarly, dynamic_cast
in C++ and instanceof
in Java do not do type checks.
Compiled vs. Interpreted
"When source code is translated"
- Source Code: Original code (usually typed by a human into a computer)
- Translation: Converting source code into something a computer can read (i.e. machine code)
- Run-Time: Period when program is executing commands (after compilation, if compiled)
- Compiled Language: Code translated before run-time
- Interpreted Language: Code translated on the fly, during execution
Typing
"When types are checked"
5 + '3'
is an example of a type error in strongly typed languages such as Go and Python, because they don't allow for "type coercion" -> the ability for a value to change type in certain contexts such as merging two types. Weakly typed languages, such as JavaScript, won't throw a type error (results in '53'
).
- Static: Types checked before run-time
- Dynamic: Types checked on the fly, during execution
The definitions of "Static & Compiled" and "Dynamic & Interpreted" are quite similar...but remember it's "when types are checked" vs. "when source code is translated".
You'll get the same type errors irrespective of whether the language is compiled or interpreted! You need to separate these terms conceptually.
Python Example
Dynamic, Interpreted
def silly(a):
if a > 0:
print 'Hi'
else:
print 5 + '3'
silly(2)
Because Python is both interpreted and dynamically typed, it only translates and type-checks code it's executing on. The else
block never executes, so 5 + '3'
is never even looked at!
What if it was statically typed?
A type error would be thrown before the code is even run. It still performs type-checking before run-time even though it is interpreted.
What if it was compiled?
The else
block would be translated/looked at before run-time, but because it's dynamically typed it wouldn't throw an error! Dynamically typed languages don't check types until execution, and that line never executes.
Go Example
Static, Compiled
package main
import ("fmt"
)
func silly(a int) {
if (a > 0) {
fmt.Println("Hi")
} else {
fmt.Println("3" + 5)
}
}
func main() {
silly(2)
}
The types are checked before running (static) and the type error is immediately caught! The types would still be checked before run-time if it was interpreted, having the same result. If it was dynamic, it wouldn't throw any errors even though the code would be looked at during compilation.
Performance
A compiled language will have better performance at run-time if it's statically typed (vs. dynamically); knowledge of types allows for machine code optimization.
Statically typed languages have better performance at run-time intrinsically due to not needing to check types dynamically while executing (it checks before running).
Similarly, compiled languages are faster at run time as the code has already been translated instead of needing to "interpret"/translate it on the fly.
Note that both compiled and statically typed languages will have a delay before running for translation and type-checking, respectively.
More Differences
Static typing catches errors early, instead of finding them during execution (especially useful for long programs). It's more "strict" in that it won't allow for type errors anywhere in your program and often prevents variables from changing types, which further defends against unintended errors.
num = 2
num = '3' // ERROR
Dynamic typing is more flexible, which some appreciate. It typically allows for variables to change types, which can result in unexpected errors.
Statically typed languages type-check at compile time and the type can NOT change. (Don't get cute with type-casting comments, a new variable/reference is created).
Dynamically typed languages type-check at run-time and the type of an variable CAN be changed at run-time.
Statically typed languages: each variable and expression is already known at compile time.
(int a;
a can take only integer type values at runtime)
Examples: C, C++, Java
Dynamically typed languages: variables can receive different values at runtime and their type is defined at run time.
(var a;
a can take any kind of values at runtime)
Examples: Ruby, Python.
Sweet and simple definitions, but fitting the need: Statically typed languages binds the type to a variable for its entire scope (Seg: SCALA) Dynamically typed languages bind the type to the actual value referenced by a variable.
- In a statically typed language, a variable is associated with a type which is known at compile time, and that type remains unchanged throughout the execution of a program. Equivalently, the variable can only be assigned a value which is an instance of the known/specified type.
- In a dynamically typed language, a variable has no type, and its value during execution can be anything of any shape and form.
Statically typed languages like C++, Java and Dynamically typed languages like Python differ only in terms of the execution of the type of the variable. Statically typed languages have static data type for the variable, here the data type is checked during compiling so debugging is much simpler...whereas Dynamically typed languages don't do the same, the data type is checked which executing the program and hence the debugging is bit difficult.
Moreover they have a very small difference and can be related with strongly typed and weakly typed languages. A strongly typed language doesn't allow you to use one type as another eg. C and C++ ...whereas weakly typed languages allow eg.python
dynamically typed language helps to quickly prototype algorithm concepts without the overhead of about thinking what variable types need to be used (which is a necessity in statically typed language).
Static typed languages (compiler resolves method calls and compile references):
- usually better performance
- faster compile error feedback
- better IDE support
- not suited for working with undefined data formats
- harder to start a development when model is not defined when
- longer compilation time
- in many cases requires to write more code
Dynamic typed languages (decisions taken in running program):
- lower performance
- faster development
- some bugs might be detected only later in run-time
- good for undefined data formats (meta programming)
Statically Typed
The types are checked before run-time so mistakes can be caught earlier.
Examples = c++
Dynamically Typed
The types are checked during execution.
Examples = Python
Static Typing: The languages such as Java and Scala are static typed.
The variables have to be defined and initialized before they are used in a code.
for ex. int x; x = 10;
System.out.println(x);
Dynamic Typing: Perl is an dynamic typed language.
Variables need not be initialized before they are used in code.
y=10; use this variable in the later part of code
'development' 카테고리의 다른 글
JavaScript에서 올해 가져 오기 (0) | 2020.09.28 |
---|---|
PHP에서 요청 유형 감지 (GET, POST, PUT 또는 DELETE) (0) | 2020.09.28 |
새 배열을 만들지 않고 기존 JavaScript 배열을 다른 배열로 확장하는 방법 (0) | 2020.09.28 |
jQuery AJAX 제출 양식 (0) | 2020.09.28 |
bash에서 ls를 사용하여 디렉토리 만 나열 : 검사 (0) | 2020.09.28 |