동적 언어에 실질적인 이점이 있습니까? [닫은]


29

먼저 Java가 내가 사용한 유일한 언어라고 말하고 싶습니다.이 주제에 대해 무지를 용서하십시오.

동적으로 입력 된 언어를 사용하면 변수에 값을 넣을 수 있습니다. 예를 들어 다음 함수 (psuedocode)를 작성할 수 있습니다.

void makeItBark(dog){
    dog.bark();
}

그리고 당신은 그 안에 어떤 가치를 전달할 수 있습니다. 값에 bark()메소드가있는 한 코드가 실행됩니다. 그렇지 않으면 런타임 예외 또는 이와 유사한 것이 발생합니다. (내가 틀렸다면 나를 정정하십시오).

이것은 유연성을 제공합니다.

그러나 나는 동적 언어에 대해 약간의 독서를했고 사람들이 말하는 것은 동적 언어로 코드를 디자인하거나 작성할 때 정적 형식의 언어에서와 마찬가지로 유형에 대해 생각하고 고려한다는 것입니다.

예를 들어 makeItBark()함수를 작성할 때 '수 피할 수있는 것'만 받아들이려고하지만 이런 종류의 것만 전달해야합니다. 유일한 차이점은 이제 실수했을 때 컴파일러가 알려주지 않는다는 것입니다.

물론,이 접근 방식의 장점은 정적 언어에서 '이 함수는 짖을 수있는 모든 것을 받아들입니다'를 달성하려면 명시 적 Barker인터페이스 를 구현해야한다는 것 입니다. 그럼에도 불구하고 이것은 사소한 이점처럼 보입니다.

뭔가 빠졌습니까? 동적으로 유형이 지정된 언어를 사용하여 실제로 얻는 것은 무엇입니까?


6
makeItBark(collections.namedtuple("Dog", "bark")(lambda x: "woof woof")). 그 주장은 클래스 가 아니며 익명의 튜플입니다. 오리 타이핑 ( "...처럼 떨리면 ...")을 사용하면 본질적으로 제한이없고 구문 적 오버 헤드가없는 임시 인터페이스를 수행 할 수 있습니다. Java와 같은 언어 로이 작업을 수행 할 수는 있지만 많은 혼란을 겪습니다. Java의 함수에 ArrayList가 필요하고 다른 컬렉션 유형을 제공하려는 경우 SOL입니다. 파이썬에서는 올 수조차 없습니다.
Phoshi

2
이런 종류의 질문을하기 전에 물어되었습니다 여기 , 여기 , 그리고 여기 . 특히 첫 번째 예는 귀하의 질문에 대답하는 것 같습니다. 어쩌면 당신은 그것을 구별하기 위해 당신의 문구를 바꿀 수 있습니까?
logc

3
예를 들어 C ++에서는 bark()메소드 가있는 모든 유형 T에서 작동하는 템플릿 함수를 가질 수 있으며 컴파일러는 무언가 잘못 전달했을 때 불평하지만 실제로 bark ()가 포함 된 인터페이스를 선언하지 않고도 불평합니다.
Wilbert

2
@Phoshi Python의 인수는 여전히 특정 유형이어야합니다. 예를 들어 숫자 일 수 없습니다. 일부 사용자 지정 getMember함수를 통해 멤버를 검색하는 고유 한 개체 구현이있는 경우 대신에 makeItBark호출했기 때문에 작동이 중단됩니다 . 코드가 작동하게 만드는 것은 모든 사람이 파이썬의 기본 객체 유형을 사용하는 것에 암시 적으로 동의한다는 것입니다. dog.barkdog.getMember("bark")
Doval

2
@Phoshi Just because I wrote makeItBark with my own types in mind doesn't mean you can't use yours, wheras in a static language it probably /does/ mean that.내 대답에서 지적했듯이 일반적인 경우는 아닙니다 . Java와 C #의 경우에 해당하지만 이러한 언어에는 유형 및 모듈 시스템이 무너져 정적 타이핑이 수행 할 수있는 작업을 나타내지 않습니다. makeItBarkC ++이나 D와 같은 기능이없는 언어도 포함하여 여러 정적으로 형식화 된 언어로 완벽하게 제네릭 을 작성할 수 있습니다 .
Doval

답변:


35

동적 유형 언어는 단일 유형입니다

타입 시스템을 비교할 때 동적 타이핑에는 이점이 없습니다. 동적 타이핑은 정적 타이핑의 특별한 경우입니다 . 모든 변수가 동일한 유형을 갖는 정적 타입 언어입니다. 모든 변수를 유형 Object으로하고 "객체"값을 유형으로 하여 Java에서 동일한 것을 달성 할 수 있습니다 (간결함) Map<String, Object>.

void makeItBark(Object dog) {
    Map<String, Object> dogMap = (Map<String, Object>) dog;
    Runnable bark = (Runnable) dogMap.get("bark");
    bark.run();
}

따라서 리플렉션이 없어도 거의 정적으로 유형이 지정된 언어에서 구문상의 편의성을 제외하고 동일한 효과를 얻을 수 있습니다. 추가적인 표현력을 얻지 못하고 있습니다. 반대로, 동적으로 유형이 지정된 언어에서는 변수를 특정 유형으로 제한하는 기능 이 거부 되므로 표현력 이 떨어 집니다.

정적으로 입력 된 언어로 오리 껍질 만들기

또한 정적으로 형식이 좋은 언어를 사용하면 작업이있는 모든 유형에서 작동하는 코드를 작성할 수 있습니다 bark. Haskell에서 이것은 유형 클래스입니다.

class Barkable a where
    bark :: a -> unit

이는 어떤 유형 a이 Barkable로 간주 되려면 bark해당 유형의 값을 가져오고 아무것도 반환하지 않는 함수 가 있어야 한다는 제약 조건을 나타냅니다.

그런 다음 Barkable제약 조건 에서 일반 함수를 작성할 수 있습니다 .

makeItBark :: Barkable a => a -> unit
makeItBark barker = bark (barker)

이것은 요구 사항을 makeItBark충족시키는 모든 유형에 적용 Barkable됩니다. 이것은 유사 보일 수 있습니다 interface자바 나 C #에서하지만 하나의 큰 장점이 있습니다 - 유형은 지정하지 않아도 앞까지 그들이 만족 형 클래스를. 필자가 작성하지 않은 타사 유형 이라도 언제든지 유형 Duck이 있다고 말할 수 있습니다 . 실제로 작성자가 함수를 작성하지 않았다는 것은 중요하지 않습니다 . 만족 하는 언어를 말할 때 사실을 제공 할 수 있습니다 .BarkableDuckDuckbarkDuckBarkable

instance Barkable Duck where
    bark d = quack (punch (d))

makeItBark (aDuck)

이것은 Ducks가 짖을 수 있으며, 짖는 소리를 내기 전에 오리펀칭하여 짖는 기능을 구현합니다 . 그 길 makeItBark에서 오리를 부를 수 있습니다 .

Standard ML그리고 OCaml훨씬 더 유연 당신이 만족 수 있다는 점에서입니다 같은 하나 이상의 방법으로 형 클래스를. 이 언어에서는 정수를 기존 순서를 사용하여 순서 를 정한 다음 뒤집을 수 있고 나눌 수도 있음을 말할 수 있습니다 (예 : 10 > 510은 5로 나눌 수 있기 때문에). Haskell에서는 유형 클래스를 한 번만 인스턴스화 할 수 있습니다. (이 하스켈은 자동으로 전화를해도 괜찮은지 것을 알 수 있습니다 bark오리에, SML 또는 OCaml의에서 당신에 대해 명시 될 필요가 있는 bark 하나 이상이있을 수 있기 때문에, 당신이 원하는 기능을 수행합니다.)

간결

물론, 구문상의 차이가 있습니다. 제시 한 파이썬 코드는 내가 작성한 Java 코드보다 훨씬 간결합니다. 실제로, 간결함은 동적 유형 언어의 매력에 큰 부분을 차지합니다. 그러나 형식 유추를 사용하면 모든 변수 의 형식을 명시 적으로 작성하지 않아도되므로 정적으로 형식이 지정된 언어로 간결한 코드를 작성할 수 있습니다 . 정적으로 유형이 지정된 언어는 동적 입력에 대한 기본 지원을 제공하여 모든 캐스팅 및 맵 조작 (예 : C # dynamic) 의 상세 정보를 제거합니다 .

정확하지만 잘못된 유형의 프로그램

공평하게, 정적 타이핑은 타입 체커가 그것을 확인할 수 없더라도 기술적으로 올바른 일부 프로그램을 배제해야합니다. 예를 들면 다음과 같습니다.

if this_variable_is_always_true:
    return "some string"
else:
    return 6

ifelse 분기가 발생하지 않더라도 대부분의 정적으로 유형이 지정된 언어는이 문장을 거부 합니다. 실제로이 유형의 코드를 사용하는 사람은없는 것 같습니다. 유형 검사기에 너무 영리한 것은 미래의 코드 관리자가 당신과 당신의 친척을 저주하게 할 것입니다. 예를 들어 누군가가 4 개의 오픈 소스 Python 프로젝트를 Haskell로 성공적으로 변환했습니다 . 즉, 정적 형식이 좋은 언어로는 컴파일 할 수없는 작업을 수행하지 않았습니다. 또한 컴파일러는 단위 테스트에서 포착하지 못한 몇 가지 유형 관련 버그를 발견했습니다.

동적 타이핑에서 본 가장 강력한 주장은 Lisp의 매크로입니다. 언어의 구문을 임의로 확장 할 수 있기 때문입니다. 그러나 Typed Racket 은 매크로가있는 정적으로 유형이 지정된 Lisp의 방언이므로 정적 입력과 매크로는 상호 배타적이지 않지만 동시에 구현하기는 더 어렵습니다.

사과와 오렌지

마지막으로, 유형 시스템보다 언어에 큰 차이가 있다는 것을 잊지 마십시오. Java 8 이전에는 Java에서 모든 종류의 기능 프로그래밍을 수행 하는 것이 사실상 불가능했습니다. 간단한 람다는 4 줄의 상용구 익명 클래스 코드가 필요합니다. Java는 콜렉션 리터럴 (예 :)도 지원하지 않습니다 [1, 2, 3]. 툴링 (IDE, 디버거), 라이브러리 및 커뮤니티 지원의 품질과 가용성에 차이가있을 수도 있습니다. 누군가가 Java보다 Python이나 Ruby에서 더 생산적이라고 주장 할 때, 그 기능 불일치를 고려해야합니다. 포함 된 모든 배터리 , 언어 코어유형 시스템언어를 비교하는 것에는 차이가 있습니다 .


2
당신은 첫 번째 단락에 대한 출처를

2
@Matt Re : 1, 나는 그것이 중요하지 않다고 가정하지 않았습니다. 나는 간결하게 설명했다. Re : 2, 명시 적으로 말하지는 않았지만 "좋은"이란 "완전한 유형 유추가 있음"을 의미하며 " 실제로 코드를 유형 서명에 일치시킬 수있는 모듈 시스템을 가지고 있습니다. " C #의 인터페이스. Re 3, 증거의 부담은 동일한 구문과 기능을 가진 두 언어, 동적 유형과 전체 유형 유추를 가진 두 언어가 어떻게 주어 졌는지에 대해 설명해야합니다. 두 언어 모두에서 동일한 길이의 코드를 작성할 수 없습니다 .
Doval

3
@MattFenwick 나는 이미 그것을 정당화했다. 동일한 유형의 언어와 정적 인 유형의 동일한 기능을 가진 두 가지 언어를 감안할 때, 그들 사이의 주요 차이점은 유형 주석의 존재이며 유형 유추는 그것을 없애 버린다. 구문의 다른 차이점은 피상적이며 기능의 차이점은 비교를 사과 대 오렌지로 바꿉니다. 이 논리가 어떻게 잘못되었는지 보여줄 책임이 있습니다.
Doval

1
Boo를 살펴 봐야합니다. 형식 유추로 정적으로 입력되며 언어 구문을 확장 할 수있는 매크로가 있습니다.
메이슨 휠러

1
@Doval : 맞습니다. BTW, 람다 표기법은 함수형 프로그래밍에서만 독점적으로 사용되지 않습니다. 내가 아는 한 스몰 토크에는 익명의 블록이 있으며 스몰 토크는 가능한 객체 지향적입니다. 따라서 종종 해결책은 익명 함수 또는 정확히 하나의 익명 메소드가있는 익명 객체인지 여부에 관계없이 일부 매개 변수를 사용하여 익명의 코드 블록을 전달하는 것입니다. 이 두 가지 구성은 두 가지 다른 관점 (기능적, 객체 지향적)에서 본질적으로 동일한 아이디어를 표현한다고 생각합니다.
Giorgio

11

이것은 어렵고 주관적인 문제입니다. (그리고 귀하의 질문은 의견 기반으로 닫힐 수 있지만, 이것이 나쁜 질문을 의미하는 것은 아닙니다. 반대로 메타 언어 질문에 대한 생각조차도 좋은 징조입니다-Q & A 형식에 적합하지 않습니다. 이 포럼의

고급 언어의 요점은 프로그래머가 컴퓨터로 할 수있는 일 을 제한 하는 것입니다. 그들은 목적은 사용자에게 제공하는 것입니다 생각 때문에 이것은 많은 사람들에게 놀라운 전력을하고 달성 . 그러나 Prolog, C ++ 또는 List로 작성하는 모든 것이 결국 기계 코드로 실행되므로 프로그래머가 이미 어셈블리 언어에서 제공하는 것보다 더 많은 기능을 제공 할 수 없습니다.

고급 언어의 요점은 프로그래머가 스스로 작성한 코드 를 더 잘 이해 하고 동일한 작업을보다 효율적으로 수행 할 수 있도록하는 것입니다. 서브 루틴 이름은 16 진 주소보다 기억하기 쉽습니다. 자동 인수 카운터는 호출 순서보다 사용하기가 더 쉽습니다. 여기서 아무런 도움없이 직접 인수의 수를 직접 가져와야합니다. 타입 시스템은 더 나아가서 주어진 장소에서 제공 할 수있는 인수 의 종류 를 제한합니다 .

여기 사람들의 인식이 다릅니다. 어떤 사람들 (나는 그들 중 하나입니다) 당신의 암호 검사 루틴이 어쨌든 정확히 두 개의 인수를 기대하고 문자열 뒤에 숫자 ID가 오는 한, 코드에서 이것을 선언하고 자동으로 알리는 것이 유용하다고 생각합니다 나중에 그 규칙을 따르는 것을 잊어 버립니다. 이러한 소규모 북 키핑을 컴파일러에 아웃소싱하면 더 높은 수준의 문제를 해결할 수 있고 시스템을보다 효율적으로 설계하고 설계 할 수 있습니다. 따라서 유형 시스템은 컴퓨터의 장점으로, 컴퓨터는 자신이 잘하는 것을, 인간은 자신이 잘하는 것을 할 수 있습니다.

다른 사람들은 상당히 다르게 본다. 컴파일러가해야 할 일을 말하는 것을 싫어합니다. 그들은 타입 선언을 결정하고 타이핑하기위한 추가적인 선행 노력을 싫어한다. 어디에서 어떤 유형과 인수를 사용할 것인지 정확하게 알려주는 계획 없이 실제 비즈니스 코드를 작성하는 탐색 적 프로그래밍 스타일을 선호합니다 . 그리고 그들이 사용하는 프로그래밍 스타일에 대해서는 꽤 사실 일 수 있습니다.

물론, 여기서는 너무 단순화되었습니다. 형식 검사는 명시 적 형식 선언과 밀접한 관련이 없습니다. 형식 유추도 있습니다. 실제로 다양한 유형의 인수를 취하는 루틴을 사용하는 프로그래밍은 불가능하고 매우 강력하고 다른 것들을 허용합니다. 많은 사람들이 그러한 여유를 성공적으로 사용할만큼주의를 기울이지 않고 일관성이 없다는 것입니다.

결국, 그러한 다른 언어가 매우 인기가 있고 죽어 가고 있다는 징후가 없다는 사실은 사람들이 프로그래밍을 매우 다르게 진행한다는 것을 보여줍니다. 프로그래밍 언어 기능은 인간의 의사 결정 과정을 더 잘 지원하는 인적 요소에 관한 것이라고 생각합니다. 사람들이 매우 다르게 작동하는 한 시장은 매우 다른 솔루션을 동시에 제공 할 것입니다.


3
답변 해주셔서 감사합니다. 어떤 사람들 은 컴파일러가해야 할 일을 말하는 것을 싫어한다고 말했습니다. [..] 어떤 유형과 인수를 어디에 사용할 것인지 정확하게 알려주는 계획없이 실제 비즈니스 코드를 작성하는 탐색 적 프로그래밍 스타일을 선호합니다. ' 이것은 내가 이해하지 못하는 것입니다. 프로그래밍은 음악 즉흥 연주와는 다릅니다. 음악에서 틀린 음을 칠 경우 멋지게 들릴 수 있습니다. 프로그래밍에서, 존재하지 않는 함수에 무언가를 전달하면 불쾌한 버그가 발생할 가능성이 큽니다. (다음 의견에서 계속).
Aviv Cohn

3
동의하지만 많은 사람들 동의 하지 않습니다 . 그리고 사람들은 그들의 정신적 선입견에 대해 매우 소중합니다. 특히 그들이 종종 모르기 때문입니다. 그렇기 때문에 프로그래밍 스타일에 대한 논쟁은 대개 논쟁이나 싸움으로 변질되며 인터넷에서 임의의 낯선 사람으로 시작하는 것이 거의 유용하지 않습니다.
Kilian Foth

1
동적 언어를 사용하는 사람들은 정적 언어를 사용하는 사람들처럼 유형을 고려하는 이유입니다. 함수를 작성할 때 특정 종류의 인수를 취해야하기 때문입니다. 컴파일러가이를 시행하는지 여부는 중요하지 않습니다. 따라서 정적 타이핑이 도움이되며 동적 타이핑은 그렇지 않습니다. 두 경우 모두 함수는 특정 종류의 입력을 가져야합니다. 따라서 동적 입력의 이점이 무엇인지 알 수 없습니다. '탐사 프로그래밍 스타일'을 선호하더라도 원하는 것을 함수에 전달할 수는 없습니다.
Aviv Cohn

1
사람들은 종종 매우 다른 유형의 프로젝트 (특히 규모)에 대해 이야기합니다. 웹 사이트의 비즈니스 로직은 완전한 ERP 시스템과 비교할 때 매우 간단합니다. 문제가 발생할 위험이 적으며 일부 코드를 매우 간단하게 재사용 할 수 있다는 이점이 더 적합합니다. 데이터 구조에서 Pdf (또는 일부 HTML)를 생성하는 코드가 있다고 가정 해보십시오. 이제 다른 데이터 소스가 있습니다 (처음에는 일부 REST API의 JSON이었고 이제는 Excel 가져 오기 도구입니다). Ruby와 같은 언어에서는 첫 번째 구조를 '시뮬레이션'하고 '수피를 만들고'PDF 코드를 재사용하는 것이 매우 쉽습니다.
thorsten müller

@Prog : 동적 언어의 진정한 장점은 정적 타입 시스템으로는 어려운 것들을 설명 할 때입니다. 예를 들어 파이썬의 함수는 함수 참조, 람다, 함수 객체 또는 신이 무엇을 알고 있으며 모두 동일하게 작동한다는 것을 알 수 있습니다. 다른 객체를 감싸고 구문 오버 헤드가없는 메소드를 자동으로 전달하는 객체를 만들 수 있으며 모든 함수에는 기본적으로 마술처럼 유형이 지정되어 있습니다. 역동적 인 언어는 빠르게 일을 처리하는 데 놀랍습니다.
Phoshi

5

동적 언어를 사용하여 작성된 코드는 정적 유형 시스템에 연결되지 않습니다. 따라서, 이러한 커플 링의 결여는 열악한 / 부적절한 정적 유형 시스템에 비해 이점이 있지만 (큰 정적 유형 시스템에 비해 세척 또는 단점 일 수 있음).

또한 동적 언어의 경우 정적 유형 시스템을 설계, 구현, 테스트 및 유지 관리 할 필요가 없습니다. 이것은 정적 타입 시스템을 가진 언어에 비해 구현이 더 간단해질 수 있습니다.


2
사람들이 궁극적으로 단위 테스트를 통해 기본 정적 유형 시스템을 다시 구현하지 않는 경향이 있습니까 (좋은 테스트 범위를 목표로 할 때)?
Den

또한 "커플 링"이란 무엇을 의미합니까? 예를 들어 마이크로 서비스 아키텍처에서 어떻게 나타날까요?
Den

@ 덴 1) 그러나 좋은 질문이지만 OP와 범위 내에서 벗어났습니다. 2) 나는 이런 의미에서 결합 을 의미 한다. 간단히 말해서, 다른 유형 시스템은 해당 언어로 작성된 코드에 대해 서로 다른 (호환되지 않는) 제약 조건을 부과합니다. 죄송합니다. 마지막 질문에 대답 할 수 없습니다. 이와 관련하여 마이크로 서비스의 특별한 점을 이해하지 못합니다.

2
@ Den : 아주 좋은 점 : 필자는 종종 파이썬에서 작성하는 단위 테스트가 정적 타입 언어의 컴파일러에 의해 잡힐 수있는 오류를 발견한다는 것을 관찰합니다.
Giorgio

@MattFenwick : 동적 언어의 경우 정적 유형 시스템을 설계, 구현, 테스트 및 유지 관리 할 필요가 없다는 장점이 있습니다. 그리고 Den은 종종 코드에서 직접 타입을 디자인하고 테스트해야한다는 것을 관찰했습니다. 따라서 노력이 제거되지 않고 언어 설계에서 응용 프로그램 코드로 이동되었습니다.
Giorgio
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.