programing

약하게 타이핑된 언어에 관한 명백한 모순에 대한 해명을 요구하고 있다.

goodcopy 2022. 8. 8. 15:43
반응형

약하게 타이핑된 언어에 관한 명백한 모순에 대한 해명을 요구하고 있다.

타이핑이 강한 것은 이해하지만 타이핑이 약한 것의 예를 찾을 때마다 자동으로 타이핑을 강요/변환하는 프로그래밍 언어의 예를 발견하게 됩니다.

예를 들어, 타이핑이라는 이름의 이 문서에서 다음과 같이 입력합니다. 강도와 약하고 정적인 것과 Dynamic에 따르면 Python은 다음과 같은 경우 예외가 발생하기 때문에 강하게 입력된다고 합니다.

파이썬

1 + "1"
Traceback (most recent call last):
File "", line 1, in ? 
TypeError: unsupported operand type(s) for +: 'int' and 'str'

다만, Java나 C#에서는 가능한 일이며, 그것만으로 약하게 입력한다고는 생각하지 않습니다.

자바

  int a = 10;
  String b = "b";
  String result = a + b;
  System.out.println(result);

C#

int a = 10;
string b = "b";
string c = a + b;
Console.WriteLine(c);

약자형 언어라는 이름의 또 다른 기사에서 저자는 펄이 약자로 입력되는 이유는 단순히 문자열을 숫자에 연결할 수 있기 때문이며, 그 반대의 경우도 명시적인 변환 없이 연결할 수 있기 때문이라고 말합니다.

$a=10;
$b="a";
$c=$a.$b;
print $c; #10a

같은 예에서 Perl은 약하게 입력되지만 Java와 C#은 입력되지 않습니다.

이런, 헷갈리네enter image description here

저자들은 다른 유형의 값에 대한 특정 연산의 적용을 방해하는 언어는 강하게 타이핑되고, 반대로 약하게 타이핑된다는 것을 암시하는 듯하다.

따라서 어떤 언어에서 (perl과 같이) 유형 간에 많은 자동 변환이나 강제성을 제공하는 경우, 결과적으로 약하게 입력되는 것으로 간주될 수 있지만, 일부 변환만 제공하는 다른 언어들은 강하게 입력되는 것으로 간주될 수 있다고 믿고 싶은 충동을 느꼈습니다.

그러나 나는 내가 이 내막에서 틀렸음에 틀림없다고 믿는 경향이 있다. 다만 나는 그것을 왜 또는 어떻게 설명해야 할지 모를 뿐이다.

그래서 질문하겠습니다.

  • 언어가 정말로 약하게 입력된다는 것은 무엇을 의미할까요?
  • 언어에 의한 자동 변환/자동 강제와 관련이 없는 약한 타이핑의 좋은 예를 들어 주시겠습니까?
  • 언어를 약하게 타이핑하는 동시에 강하게 타이핑할 수 있습니까?

업데이트: 이 질문은 2012년 10월 15일 블로그의 주제였습니다.좋은 질문 감사합니다!


언어가 "약하게 타이핑된다"는 것은 정말로 무엇을 의미합니까?

'이 언어는 내가 혐오하는 타입의 시스템을 사용한다'는 뜻이다.반면, "강자형" 언어는 제가 좋아하는 유형 체계를 가진 언어입니다.

그 용어들은 본질적으로 무의미하므로 피해야 한다.위키피디아는 "강력하게 유형화된"에 대한 11가지 다른 의미를 나열하고 있으며, 그 중 몇 가지는 모순적이다.이는 "강형" 또는 "약형"이라는 용어가 포함된 대화에서 혼동이 발생할 가능성이 높다는 것을 나타냅니다.

확실히 말할 수 있는 것은, 논의되고 있는 「강력하게 입력된」언어에는, 런타임이나 컴파일시에, 한층 더 타입 시스템에 제한이 있어 논의되고 있는 「약하게 입력된」언어에는 결여되어 있는 것입니다.그 제약이 무엇인지는 추가 컨텍스트 없이 결정할 수 없다.

"강형"과 "약형"을 사용하는 대신 어떤 유형의 안전성을 의미하는지 자세히 설명해야 합니다.를 들어 C#은 대부분 정적으로 입력된 언어이며, 타입 세이프 언어 및 메모리 세이프 언어입니다.C# 에서는, 이러한 3 종류의 「강력한」타이핑이 모두 위반될 수 있습니다.캐스트 연산자가 정적 입력을 위반하여 컴파일러에게 "당신이 아는 것보다 이 식의 런타임 유형에 대해 더 많이 알고 있습니다."라고 말합니다.개발자가 잘못된 경우 유형 안전을 보호하기 위해 런타임에서 예외가 발생합니다.개발자가 타입의 안전성이나 메모리 안전을 해치고 싶은 경우는, 「안전하지 않은」블록을 만들어 타입의 안전 시스템을 끄면 됩니다.안전하지 않은 블록에서는 포인터 마법을 사용하여 int를 플로트로 취급하거나(안전성을 위반), 소유하지 않은 메모리에 쓸 수 있습니다(메모리 안전성을 위반).

C#은 컴파일 시 및 런타임 시 체크되는 타입 제한을 가하기 때문에 컴파일 시 체크나 런타임 체크를 적게 하는 언어에 비해 "강력하게 타이핑된" 언어가 됩니다.또한 C#은 특별한 상황에서 이러한 제한에 대해 최종 실행을 수행할 수 있으므로 이러한 최종 실행을 허용하지 않는 언어에 비해 "취약하게 입력된" 언어가 됩니다.

어떤 게 진짜예요?말할 수 없다; 그것은 화자의 관점과 다양한 언어의 특징에 대한 그들의 태도에 달려있다.

다른 사람들이 지적했듯이, "강하게 입력된" 용어와 "약하게 입력된" 용어의 의미가 너무 다양해서 질문에 대한 답은 단 한 개도 없습니다.단, 질문에서 Perl을 구체적으로 언급하셨기 때문에 Perl이 약하게 입력되어 있는 것을 설명하겠습니다.

요점은 Perl에서는 "integer variable", "float variable", "string variable" 또는 "boolean variable"과 같은 것이 존재하지 않는다는 것입니다.실제로 사용자가 알 수 있는 한 정수, 부동, 문자열 또는 부울 값조차 없습니다.사용자가 가진 것은 "스칼라"뿐이며, 이 모든 것이 동시에 표시됩니다.예를 들어 다음과 같이 쓸 수 있습니다.

$foo = "123" + "456";           # $foo = 579
$bar = substr($foo, 2, 1);      # $bar = 9
$bar .= " lives";               # $bar = "9 lives"
$foo -= $bar;                   # $foo = 579 - 9 = 570

물론, 당신이 정확히 지적했듯이, 이 모든 것은 단지 강압적인 유형으로 보일 수 있다.하지만 중요한 것은 Perl에서는 항상 타입이 강요된다는 것입니다.사실 사용자가 변수의 내부 "유형"이 무엇인지 구별하는 것은 매우 어렵습니다. 위의 예에서는 두 번째 줄에 있습니다.$bar문자열입니다."9"또는 번호9Perl에 관한 한, 그것들은 같은 것이기 때문에, 거의 의미가 없습니다.실제로 Perl 스칼라는 내부적으로 문자열과 숫자 값을 동시에 가질 수도 있습니다. 예를 들어 다음과 같습니다.$foo위의 두 번째 줄 뒤에 있습니다.

이 모든 것의 반대점은 Perl 변수가 입력되지 않았기 때문에(또는 내부 유형을 사용자에게 공개하지 않기 때문에) 연산자는 다른 유형의 인수에 대해 다른 작업을 수행하도록 오버로드될 수 없다는 것입니다. 연산자는 어떤 값을 구하는지 알 수 없기 때문에 "이 연산자는 숫자에 대해 X, 문자열에 대해 Y를 할 것입니다."라고만 말할 수 없습니다.그 주장은 그렇다.

예를 들어 Perl에는 숫자 덧셈 연산자가 있으며 둘 다 필요합니다.+및 문자열 연결 연산자(.위에서 보셨듯이 스트링을 추가해도 괜찮습니다."1" + "2" == "3"또는 번호를 연결하기 위해(1 . 2 == 12)와 마찬가지로 수치 비교 연산자==,!=,<,>,<=,>=그리고.<=>문자열 비교 연산자를 사용하는 동안 인수의 숫자 값을 비교합니다.eq,ne,lt,gt,le,ge그리고.cmp사전 편찬적으로 문자열과 비교합니다.그렇게2 < 10,그렇지만2 gt 10(단,"02" lt 10,하는 동안에"02" == 2(JavaScript와 같은 다른 특정 언어는 연산자 오버로드와 함께 Perl과 같은 약한 타이핑에 대응하려고 합니다.이것은 종종 추악함으로 이어집니다. 예를 들어, 에 대한 연관성의 상실과 같은+.)

(여기서 문제가 되는 것은 Perl 5에는 과거의 이유로 비트 논리 연산자와 같은 몇 가지 코너 케이스가 있다는 것입니다.이러한 케이스의 동작은 인수의 내부 표현에 따라 달라집니다.내부 표현은 놀라운 이유로 변경될 수 있고, 따라서 주어진 상황에서 이러한 운영자가 무엇을 할 것인지 예측하는 것은 어려울 수 있기 때문에 일반적으로 성가신 설계 결함으로 간주됩니다.)

하지만 Perl은 강력한 타입을 가지고 있다고 주장할 수 있습니다.그것은 당신이 예상할 수 있는 타입이 아닙니다.특히 위에서 설명한 '스칼라' 유형 외에 Perl에는 '어레이'와 '해시'의 두 가지 구조화 유형도 있습니다.이는 스칼라와는 매우 달라 Perl 변수에는 유형을 나타내는 다른 시그널이 있습니다($스칼라,@어레이의 경우,%해시용).1이러한 유형 사이에는 강제 규칙이 있으므로 를 들어 다음과 같이 쓸 수 있습니다. %foo = @bar그 중 상당수는 손해를 보고 있습니다.예를 들어,$foo = @bar배열 길이를 할당합니다.@bar로.$foo내용물이 아닙니다.(또한, 타입글로브나 I/O핸들 등, 자주 볼 수 없는 이상한 타입도 몇 가지 있습니다.

또, 이 훌륭한 설계에서는, 특별한 종류의 스칼라(또한 표준 스칼라와 구별 가능)인 참조 타입의 존재에 약간의 문제가 있습니다.ref오퍼레이터).참조를 일반 스칼라로 사용할 수 있지만 문자열/숫자 값은 특별히 유용하지 않으며 일반 스칼라 연산을 사용하여 수정하면 특별한 참조 정밀도가 손실되는 경향이 있습니다.또한2 모든 Perl 변수는bless클래스로 변환하여 해당 클래스의 객체로 만듭니다. Perl의 OO 클래스 시스템은 위에서 설명한 원시 유형(또는 무형) 시스템과 다소 직교하지만, 오리 타이핑 패러다임을 따른다는 의미에서도 "약함"입니다.일반적인 의견은 Perl에서 객체의 클래스를 체크하고 있는 자신을 발견하면 잘못된 행동을 하고 있다는 것입니다.


1 실제로 기호는 액세스되는 값의 유형을 나타냅니다.따라서 어레이의 첫 번째 스칼라 등@foo라고 표시되어 있다.$foo[0]자세한 내용은 perlfaq4를 참조하십시오.

2 Perl 내의 오브젝트는 (통상은) 오브젝트에 대한 참조를 통해 액세스 됩니다만, 실제로 얻을 수 있는 것은,blessed는 참조 포인트가 되는(어나니머스) 변수입니다.그러나 축복은 실제로 변수의 속성이지 그 가치가 아니기 때문에, 예를 들어 실제 축복받은 변수를 다른 변수에 할당하는 것은 얕고 축복받지 않은 복사본을 제공할 뿐입니다.자세한 내용은 perlobj를 참조하십시오.

Eric이 말한 것 외에 다음 C 코드를 고려합니다.

void f(void* x);

f(42);
f("hello");

Python, C#, Java 등의 언어와는 달리 위의 언어들은 유형 정보가 손실되기 때문에 약하게 입력됩니다.Eric은 C#에서 컴파일러에 캐스팅을 함으로써 컴파일러를 회피할 수 있다고 올바르게 지적하고 "이 변수의 유형에 대해 당신보다 내가 더 잘 알고 있다"고 효과적으로 말합니다.

그래도 런타임은 여전히 유형을 확인합니다!캐스트가 유효하지 않은 경우 런타임 시스템이 캐스트를 포착하여 예외를 발생시킵니다.

유형 삭제에서는 이러한 현상이 발생하지 않고 유형 정보가 폐기됩니다.에의 캐스팅void*C에서 바로 그렇게 합니다.이 점에서 위의 내용은 다음과 같은 C# 메서드 선언과는 근본적으로 다릅니다.void f(Object x).

(기술적으로는 C#에서는 안전하지 않은 코드 또는 마샬링에 의한 타입 삭제도 가능합니다).

이것은 글자만큼 약하게 입력되었다.그 외의 모든 것은 정적 유형 확인과 동적 유형 확인의 문제일 뿐입니다. 즉, 유형이 확인되는 시간의 문제입니다.

완벽한 예는 Wikipedia의 Strong Typing 기사입니다.

일반적으로 타이핑이 강하다는 것은 프로그래밍 언어가 발생 가능한 혼합에 엄격한 제한을 가한다는 것을 의미합니다.

약한 타이핑

a = 2
b = "2"

concatenate(a, b) # returns "22"
add(a, b) # returns 4

강력한 타이핑

a = 2
b = "2"

concatenate(a, b) # Type Error
add(a, b) # Type Error
concatenate(str(a), b) #Returns "22"
add(a, int(b)) # Returns 4

약한 타이핑 언어는 다른 타입을 오류 없이 혼재시킬 수 있습니다.강력한 유형의 언어를 사용하려면 입력 유형이 예상 유형이어야 합니다.강력한 타입 언어에서는 타입을 변환할 수 있습니다(str(a)는 정수를 문자열로 변환합니다.int(b)).

이것은 모두 타이핑의 해석에 달려 있습니다.

다른 사람의 코멘트나 기고등의 코멘트로, 그 사람의 레퍼런스를 읽고, 그 사람의 레퍼런스를 더듬어, 흥미로운 정보를 발견해, 자신의 연구로 토론에 공헌하고 싶다고 생각하고 있습니다.제안하신 바와 같이, 실용적이라기보다는 이론적으로 보이기 때문에, 이 대부분은 프로그래머 포럼에서 더 잘 논의될 가능성이 높습니다.

이론적인 관점에서, 나는 루카 카델리와 피터 웨그너의 "유형의 이해, 데이터 추상화, 다형성에 대하여"라는 글은 내가 읽은 것 중 최고의 주장 중 하나라고 생각한다.

타입은, 제멋대로 또는 의도하지 않은 사용으로부터 기본적인 비타이프 표현을 보호하는 의류 세트(또는 갑옷 세트)로 간주할 수 있습니다.기본 표현을 숨기고 객체가 다른 객체와 상호 작용하는 방식을 제한하는 보호 덮개를 제공합니다.타입이 없는 시스템에서는, 타입이 없는 오브젝트는, 그 기초가 되는 표현이 모든 사람이 볼 수 있도록 공개되어 있는 점에서, 벌거벗겨져 있습니다.형식 시스템을 위반하는 것은 보호복 세트를 제거하고 나체로 직접 조작하는 것을 포함합니다.

이 스테이트먼트는, 약하게 타이핑 하는 것으로써, 타입의 내부 구조에 액세스 해, 마치 다른 타입(다른 타입)인 것처럼 조작할 수 있는 것을 나타내고 있는 것 같습니다.안전하지 않은 코드(Eric에 의해 언급됨) 또는 Konrad에 의해 언급된 c타입 삭제 포인터로 우리가 무엇을 할 수 있는지.

기사는 계속됩니다...

모든 표현식이 유형별로 일치하는 언어를 strong-typeed 언어라고 합니다.언어를 강하게 입력하면 해당 컴파일러는 해당 언어가 허용하는 프로그램이 유형 오류 없이 실행됨을 보장할 수 있습니다.일반적으로 우리는 강력한 타이핑을 위해 노력하고, 가능하면 정적 타이핑을 채택해야 합니다.모든 정적으로 입력된 언어는 강하게 입력되지만 그 반대가 반드시 참인 것은 아닙니다.

따라서 타이핑이 강하다는 것은 오타가 없다는 것을 의미하고, 타이핑이 약하다는 것은 그 반대, 즉 오타가 있을 가능성이 있다는 것을 의미한다고 추측할 수 밖에 없습니다.실행 시 또는 컴파일 시?여긴 상관없을 것 같은데

재미있는 것은 이 정의에 따르면 Perl과 같은 강력한 타입의 강제성을 가진 언어는 강력한 타입으로 간주됩니다.시스템에 장애가 있는 것이 아니라 적절하고 명확하게 정의된 동등성을 강요함으로써 타입에 대처하고 있기 때문입니다.

다른 한편으로, 내가 말할 수 있는 것은ClassCastException그리고.ArrayStoreException(Java) 및InvalidCastException,ArrayTypeMismatchException(C#에서)는 적어도 컴파일 시 약하게 타이핑되는 수준을 나타낼 수 있습니까?에릭의 대답은 이에 맞는 것 같다.

Luca Cardelli는 이 질문의 답변 중 하나에 기재된 Typeful Programming이라는 이름의 두 번째 기사에서 유형 위반의 개념을 자세히 설명합니다.

대부분의 시스템 프로그래밍 언어는 임의 유형 위반을 허용하며, 일부는 프로그램의 제한된 부분에서만 무차별적으로 허용됩니다.유형 위반과 관련된 작업을 비사운드 작업이라고 합니다.유형 위반은 다음과 같은 여러 클래스로 분류됩니다(이 중 언급할 수 있습니다).

기본값 강제:여기에는 정수, 불란, 문자, 집합 등의 변환이 포함됩니다.타입 위반은 불필요합니다.내장 인터페이스가 제공되어 타입 사운드로 강제할 수 있기 때문입니다.

이와 같이 사업자가 제공하는 형식 강압은 형식 위반으로 간주할 수 있지만, 형식 시스템의 일관성을 깨뜨리지 않는 한 약형 시스템으로 이어지지 않는다고 말할 수 있다.

이에 따라 Python, Perl, Java 또는 C# 모두 약하게 입력되지 않습니다.

Cardelli는 두 가지 유형의 비방을 언급하고 있으며, 나는 타이핑이 매우 약한 경우를 매우 잘 고려하고 있다.

주소 산술필요에 따라서, 주소나 타입 변환에 적절한 조작을 제공하는 내장(불음성) 인터페이스가 필요합니다.다양한 상황에서는 힙에 대한 포인터(콜렉터 재배치 시 매우 위험), 스택에 대한 포인터, 정적 영역에 대한 포인터 및 다른 주소 공간에 대한 포인터가 포함됩니다.경우에 따라 어레이 인덱스가 주소 계산을 대체할 수 있습니다.메모리 매핑여기에는 메모리 영역이 구조화 데이터를 포함하지만 구조화되지 않은 어레이로 간주됩니다.이것은 메모리 할당기와 수집기의 일반적인 기능입니다.

이러한 기능은 C(Konrad에서 언급)와 같은 언어 또는 의 안전하지 않은 코드를 통해 가능합니다.Net(Eric이 언급)은 정말로 약하게 타이핑하는 것을 의미합니다.

저는 지금까지의 최선의 답은 에릭의 것이라고 생각합니다.왜냐하면 이 개념의 정의는 매우 이론적이고 특정 언어에 관한 한 이 모든 개념의 해석은 논란의 여지가 있는 다른 결론으로 이어질 수 있기 때문입니다.

Weak typing does indeed mean that a high percentage of types can be implicitly coerced, attempting to guess what the coder intended.

Strong typing means that types are not coerced, or at least coerced less.

Static typing means your variables' types are determined at compile time.

Many people have recently been confusing "manifestly typed" with "strongly typed". "Manifestly typed" means that you declare your variables' types explicitly.

Python is mostly strongly typed, though you can use almost anything in a boolean context, and booleans can be used in an integer context, and you can use an integer in a float context. It is not manifestly typed, because you don't need to declare your types (except for Cython, which isn't entirely python, albeit interesting). It is also not statically typed.

C and C++ are manifestly typed, statically typed, and somewhat strongly typed, because you declare your types, types are determined at compile time, and you can mix integers and pointers, or integers and doubles, or even cast a pointer to one type into a pointer to another type.

Haskell is an interesting example, because it is not manifestly typed, but it's also statically and strongly typed.

The strong <=> weak typing is not only about the continuum on how much or how little of the values are coerced automatically by the language for one datatype to another, but how strongly or weakly the actual values are typed. In Python and Java, and mostly in C#, the values have their types set in stone. In Perl, not so much - there are really only a handful of different valuetypes to store in a variable.

Let's open the cases one by one.


Python

In Python example 1 + "1", + operator calls the __add__ for type int giving it the string "1" as an argument - however, this results in NotImplemented:

>>> (1).__add__('1')
NotImplemented

Next, the interpreter tries the __radd__ of str:

>>> '1'.__radd__(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'str' object has no attribute '__radd__'

As it fails, the + operator fails with the the result TypeError: unsupported operand type(s) for +: 'int' and 'str'. As such, the exception does not say much about strong typing, but the fact that the operator + does not coerce its arguments automatically to the same type, is a pointer to the fact that Python is not the most weakly typed language in the continuum.

한편, 파이썬에서는'a' * 5 구현되는 것은 실장되어 있습니다.

>>> 'a' * 5
'aaaaa'

그것은,

>>> 'a'.__mul__(5)
'aaaaa'

조작이 다르다는 사실에는 약간의 강력한 타이핑이 필요합니다. 그러나 그 반대입니다.*곱하기 전에 값을 숫자에 강제로 입력해도 값이 약하게 입력되지는 않습니다.


자바

Java의 예에서는String result = "1" + 1;편의상 오퍼레이터가+문자열에 대해 오버로드되었습니다.자바+연산자는 시퀀스를 Creating으로 대체합니다.StringBuilder(이것을 참조해 주세요.

String result = a + b;
// becomes something like
String result = new StringBuilder().append(a).append(b).toString()

이것은 실제 강요가 없는 매우 정적인 타이핑의 예입니다.StringBuilder에는 여기서 특별히 사용되는 메서드가 있습니다.이 메뉴얼에는, 다음과 같이 기재되어 있습니다.

의 문자열 표현을 추가합니다.Object논쟁.

전체적인 효과는 메서드에 의해 인수가 문자열로 변환된 것과 동일합니다.String.valueOf(Object)그 후 이 문자열의 문자가 이 문자 시퀀스에 추가되었습니다.

그럼 어디?

Object 인수의 문자열 표현을 반환합니다.[Returns] 인수가 다음과 같은 경우null, 다음에 같은 문자열입니다."null"; 그 이외의 경우,obj.toString()이 반환됩니다.

따라서 이것은 언어에 의한 강요가 전혀 없는 경우입니다. 모든 관심을 대상 자체에 위임합니다.


C#

여기 Jon Sket의 답변에 따르면, 교환원은+에 대한 과부하도 없습니다.stringclass - Java와 마찬가지로 정적 타이핑과 강력한 타이핑으로 컴파일러에 의해 생성된 편리함입니다.


'펠다타'가 설명하듯이

Perl에는 스칼라, 스칼라 배열, 관련 스칼라 배열의 3가지 데이터 타입이 내장되어 있습니다.이것을 「해시」라고 부릅니다.스칼라는 단일 문자열(사용 가능한 메모리에 의해서만 제한됨), 숫자 또는 (perlref에서 설명됨)에 대한 참조입니다.일반 어레이는 0부터 시작하는 숫자로 색인화된 스칼라 순서 목록입니다.해시는 연관된 문자열 키에 의해 색인화된 스칼라 값의 정렬되지 않은 모음입니다.

단, Perl에는 숫자, 부울, 문자열, null, null에 대한 개별 데이터 유형이 없습니다.undefineds, 다른 오브젝트에 대한 참조 등 - 이 모든 오브젝트에 대해 스칼라 타입이1개밖에 없습니다.스칼라 값은 0과 같습니다.문자열로 설정된 스칼라 변수는 실제로 숫자로 변경될 수 있으며, 숫자 컨텍스트에서 액세스할 경우 "단순 문자열"과 다르게 동작합니다.스칼라에는 Perl 내의 모든 것을 저장할 수 있습니다.이것은 시스템에 존재하는 오브젝트 수만큼입니다.반면 Python에서는 이름이 오브젝트를 나타낼 뿐이고 Perl에서는 이름의 스칼라 값이 변경 가능한 오브젝트입니다.게다가 오브젝트 지향형 시스템은 여기에 접착되어 있습니다.perl에는 스칼라, 리스트, 해시의 3가지 데이터 타입만 있습니다.Perl에서 사용자 정의 객체는 참조(앞의 3가지 중 하나에 대한 포인터)입니다.bless패키지에 포함시킬 수 있습니다.이러한 값은 언제든지 원하는 클래스에 적용할 수 있습니다.

Perl은 사용자가 임의로 값의 클래스를 변경할 수 있도록 합니다.Python에서는 해당 클래스에 속하는 값을 명시적으로 작성하기 위해 필요한 클래스의 값을 생성할 수 없습니다.object.__new__또는 이와 유사합니다.Python에서는 작성 후 오브젝트의 본질을 변경할 수 없습니다.Perl에서는 많은 것을 할 수 있습니다.

package Foo;
package Bar;

my $val = 42;
# $val is now a scalar value set from double
bless \$val, Foo;
# all references to $val now belong to class Foo
my $obj = \$val;
# now $obj refers to the SV stored in $val
# thus this prints: Foo=SCALAR(0x1c7d8c8)
print \$val, "\n"; 
# all references to $val now belong to class Bar
bless \$val, Bar;
# thus this prints Bar=SCALAR(0x1c7d8c8)
print \$val, "\n";
# we change the value stored in $val from number to a string
$val = 'abc';
# yet still the SV is blessed: Bar=SCALAR(0x1c7d8c8)
print \$val, "\n";
# and on the course, the $obj now refers to a "Bar" even though
# at the time of copying it did refer to a "Foo".
print $obj, "\n";

따라서 유형 ID는 변수에 약하게 결합되어 있으며, 즉석에서 모든 참조를 통해 변경될 수 있습니다.사실, 만약 당신이 한다면

my $another = $val;

\$another계급적 정체성을 가지고 있지 않지만\$val여전히 축복받은 참고가 될 것입니다.


TL;DR

Perl에 대한 약한 타이핑은 단순한 자동 강제보다 훨씬 더 많이 존재하며, 역동적이면서도 매우 강력한 타이핑 언어인 Python과는 달리 값 유형 자체가 돌로 설정되지 않는 것이 더 중요합니다.저 비단뱀은TypeError1 + "1"는 Java 또는 C#에서와 같이 도움이 되는 일을 하는 것과 반대되는 경우에도 언어가 강하게 입력되었음을 나타냅니다.

다른 많은 사람들이 표현했듯이, "강" 대 "약한" 타이핑의 전체 개념은 문제가 있습니다.

원형으로서 Smalltalk는 매우 강한 타입으로, 두 객체 간의 작업이 호환되지 않을 경우 항상 예외를 발생시킵니다.단, Smalltalk는 동적으로 입력되기 때문에 이 목록에서 강하게 입력된 언어라고 할 사람은 거의 없을 것입니다.

나는 "강" 대 "약"보다 "정적" 대 "동적"이라는 개념이 더 유용하다고 생각한다.정적 유형 언어에는 컴파일 시 파악된 모든 유형이 있으며, 그렇지 않은 경우 프로그래머는 명시적으로 선언해야 합니다.

런타임에 입력을 수행하는 동적 입력 언어와는 대조적입니다.이것은 일반적으로 다형 언어의 요건이기 때문에, 2개의 오브젝트간의 조작이 합법인지 아닌지에 대해서는, 프로그래머가 사전에 결정할 필요는 없습니다.

(Smalltalk 및 Ruby와 같은) 다형식 동적 유형 언어에서는 "유형"을 "프로토콜 준수"로 생각하는 것이 더 유용합니다.개체가 다른 개체와 동일한 방식으로 프로토콜을 준수할 경우(두 개체가 상속, 믹스인 또는 기타 부두(voodoo)를 공유하지 않더라도) 런타임 시스템에 의해 동일한 "유형"으로 간주됩니다.보다 정확하게는 이러한 시스템의 오브젝트는 자율적이며 특정 인수를 참조하는 특정 메시지에 응답하는 것이 적절한지 여부를 판단할 수 있습니다.

Want an object that can make some meaningful response to the message "+" with an object argument that describes the colour blue? You can do that in dynamically-typed languages, but it is a pain in statically-typed languages.

I like @Eric Lippert's answer, but to address the question - strongly typed languages typically have explicit knowledge of the types of variables at each point of the program. Weakly typed languages do not, so they can attempt to perform an operation that may not be possible for a particular type. It think the easiest way to see this is in a function. C++:

void func(string a) {...}

The variable a is known to be of type string and any incompatible operation will be caught at compile time.

Python:

def func(a)
  ...

The variable a could be anything and we can have code that calls an invalid method, which will only get caught at runtime.

ReferenceURL : https://stackoverflow.com/questions/9929585/seeking-clarification-on-apparent-contradictions-regarding-weakly-typed-language

반응형