OCaml 비판 : 여전히 유효합니까?


15

나는 OCaml의 완전한 초보자입니다. 최근 에이 페이지 에서 OCaml에 대한 비판이 많이있었습니다.

아주 오래된 페이지 (2007) 인 것을보고 : 현재 어떤 글 머리 기호가 여전히 유효한가? 예를 들어 : 일반 객체를 인쇄 할 수 없다는 것이 여전히 사실입니까?

나는 그 안에 표현 된 의견에 대한 토론을 찾고 있지 않다는 것을 분명히하고 싶습니다. 경고없이 정수 오버플로 사실과 같은 나열된 정보가 최신 버전의 OCaml에 여전히 올바른지 묻습니다.



3
그것들이 수정되었을 수있는 포크가 있습니다 : tryfsharp.org
Den

7
물론 당신이 연결 한 에세이의 의견은 유효하지만 이러한 비판이 당신과 관련이 있는지는 완전히 다른 문제입니다. 작성자는 공통 Lisp 배경에서 왔으므로 Lispish 값을 갖습니다. OCaml을 Lisp와 비교하는 것 이외의 다른 접근 방식을 사용하는 경우 (예 : "OCaml은 단순한 필사자를위한 하스켈"또는 "C가 기능적인 언어 인 경우 OCaml이 있음") 훨씬 만족스러운 결과를 얻을 수 있습니다. 모든 결함에 대해 OCaml은 훌륭한 언어이며 그럼에도 불구하고 그 언어를 다루는 것이 좋습니다.
amon

5
내가 아는 한 , 하드웨어에서 정수 오버 플로우를 감지 할 수있는 방법이 없으므로이를 감지 하기 위해 모든 곳에서 런타임 검사를 삽입해야합니다. 그러나 저자는 성능에 기초하여 "bignum"을 사용하지 않았다! 정적 타이핑에 대한 불만은 자동차 사고로 죽을 수 없다고 생각할 수 있기 때문에 안전 벨트가 나쁘다는 것입니다. 모듈 불변성에 대한 불만은 모듈 식 및 오류가 발생하기 쉬운 습관을 원숭이 패치하고 싶다고 말하는 것입니다. "작은 유형 동물원"은 유형 유추와 아무 관련이 없습니다. 그의 편견이 어디에 있는지 분명하다 .
Doval

2
@Doval : 물론 하드웨어에서 오버플로를 감지 할 수 있습니다. 그러나이를 다루는 것은 소프트웨어 문제입니다.
메이슨 휠러

답변:


13

이 기사는 여러 곳에서 논의됩니다.

예를 들어, OCaml은 Lisp이 아니며 완벽하지 않습니다 (무엇을 의미합니까?). 블로그 게시물에 언급 된 요점이 일상적인 O'Caml 프로그래머와 관련이 있다고 생각하지 않습니다.

O'Caml을 공부 한 후에는 C / C ++ / Java와 같이 작성하지 않아도되는 프로그램을 빌드하는 데 도움이되는 흥미로운 언어라고 생각합니다. 예를 들어 Frama-C를 살펴보십시오 .

O'Caml에 대한 최신 설명을 보려면 해당 기능 에 대해 읽으십시오 . 언어는 강력한 정적 유형 검사 기술을 촉진하여 구현이 성능은 있지만 안전한 런타임 생성에 집중할 수 있도록합니다.

중요 : 저는 OCaml 전문가가 아닙니다. 당신이 그들 중 하나이고 내가 끔찍한 것을 쓴 것을 보시면 저를 정정하십시오. 이 게시물을 적절히 편집하겠습니다.

정적 유형 확인

  • 틀린 보안 감

    이것은 사실이지만 명백합니다.

    정적 타이핑은 프로그램 속성의 하위 집합에 대해 신뢰할 수있는 증거를 제공합니다. 모든 공식 프로그램을 수락하지 않는 한 평균 (토이가 아닌) 프로그램에는 런타임시에만 관찰 될 수있는 프로그래밍 오류 버그가 적용됩니다.

    동적 검사 기술을 적용 할 수있는시기입니다. OCaml 컴파일러에는 디버깅 정보가 포함 된 실행 파일을 생성하는 플래그 등이 있습니다. 강력한 프로그램을 원하는 프로그래머는 동적 검사를 명시 적으로 구현해야합니다.

    예를 들어 커먼 리스프 (Common Lisp)에도 같은 것이 적용되지만 역동적 인 타입은 옵션 타입 선언과 컴파일러 지시어는 두 번째로 반대입니다.

  • 몇 가지 기본 유형

    여전히 적용됨 : 핵심 언어가 변경되지 않았거나 크게 변경되지 않았습니다.

  • 자동 정수 오버플로

    이것은 대부분의 언어에서 정수 오버플로가 수동으로 검사되는 표준입니다. 오버플로가 발생할 수 있는지 확인하기 위해 형식 검사 작업을 수행하는 라이브러리를 모릅니다.

  • 모듈 불변성

    1. 필자는 Functors에 대해 언급했지만 그의 예제를 어떻게 구현할 수 없는지 알 수 없습니다. 읽기 퍼스트 클래스 모듈 의 장 https://realworldocaml.org를 , 모듈을 사용할 수 있습니다 것으로 보인다 구성구축 새로운 모듈을. 물론 기존 모듈을 수정하려면 소스 코드를 수정해야하지만 프로그래밍 언어에서는 예외가 아닙니다.

    2. " 의미 적 으로 함수는 인라인으로 컴파일됩니다"

    위의 레딧 스레드가 동의하지 않아 링크 타임에 바인딩이 해결된다고 말합니다. 그러나 이것은 구현 세부 사항이며 강조 표시된 의미 론적 으로 함수가 해결되는 방식과 관련이 있다고 생각합니다 . 예:

     let f x y = x + y ;;
     let g a b = f b a ;;
     let f x y = x * y ;;
     exit (g 2 3) ;;
    

    위의 프로그램을 컴파일 및 실행시 때문에 5를 반환 g의 첫 번째 버전으로 정의 f그냥 그대로있는 경우 호출 기능 g에 대한 호출을 인라인 f. 그건 그렇고 "나쁜"것이 아니라 오캄의 이름 섀도 잉 규칙과 일치합니다.

    요약하자면 , 예, 모듈은 불변 입니다. 그러나 그들은 또한 작곡이 가능하다 .

  • 다형성으로 인한 런타임 유형 오류

    언급 된 오류를 재현 할 수 없습니다. 컴파일러 오류라고 생각합니다.

매크로 없음

실제로, 전 처리기 (OcamlP4, OcamlP5, ...) 외에는 매크로가 없습니다.

  • 래퍼 (열린 파일 포함)

    UNWIND-PROTECT가 어떻게 유용 할 수 있는지 아는 것은 실제로 더 많은 언어가없는 것을 보는 것이 고통 스럽습니다. 몇 가지 옵션이 있습니다.

    1. OCaml에서 예외 관리 개선
    2. OCaml 구문 확장
  • 장소

    OCaml에는 일반화 된 참조가 존재하지 않는다고 생각합니다.

사소한 언어 짜증

  • 레코드 필드 명명 지옥

    맞지만 모듈을 사용해야합니다.

    1. OCaml에서 두 레코드의 두 필드가 동일한 레이블을 가짐
    2. 필드 이름 확인
  • 통사론

    여전히 적용됩니다 (그러나 실제로는 구문 일뿐입니다).

  • 다형성 없음

    여전히 적용되지만 어떻게 든 Lisp의 숫자 탑 대신에 선호 하는 사람들이 있습니다 (왜 그런지 모르겠습니다). 형식 유추에 도움이된다고 가정합니다.

  • 일치하지 않는 기능 세트

    OCaml 배터리 포함 프로젝트를 참조하십시오 . 특히 배열 의 예인 BatArraymap2 입니다.

  • 동적 변수가 없습니다

    구현 가능

    1. http://okmij.org/ftp/ML/dynvar.txt
    2. http://okmij.org/ftp/ML/index.html#dynvar
  • 선택 ~ 인수 짜증

    언어 제한에 따라 Common Lisp에서 선택적 및 키워드 인수를 혼합 할 수 없습니다. 그것이 짜증나는 것을 의미합니까? (물론 매크로를 사용하여 변경할 수 있습니다 (예 : 내 답변 참조 )). O'Caml의 선택적 및 명명 된 인수에 대해서는 O'Caml 설명서 를 참조하십시오 .

  • 부분 인수 적용 불일치

    나는 이것이 실제로 실제로 성가신 것이라고 생각하지 않습니다.

  • 산술의 가독성

    보유하고 있지만 원하는 경우 숫자 문제에 R 또는 Python을 사용할 수 있습니다.

  • 자동 이름 충돌 해결

    여전히 적용되지만 문서화가 잘되어 있습니다.

  • 객체 입출력 없음

    여전히 적용됩니다.

구현, 라이브러리

이것들은 매일 매일 바뀌고 있습니다 : 확실한 답은 없습니다.

드디어,

"당신은 그것을 생각하고 그것을 사용하지 않을 생각이더라도 OCaml (또는 더 나은 Haskell)을 시도해야합니다. 그것 없이는 컴퓨터 과학 교육은 불완전합니다. Lisp와 C (또는 더 나은 아직, 어셈블리) 노출. "

... 여전히 적용됩니다.


고맙습니다, 나는 링크를 살펴볼 것이지만, 그 의견이 정당한지 묻지 않습니다. 나는 사실이 여전히 보유하고 있는지 묻고있다. 예를 들어, 대수 데이터 형식을 인쇄하는 방법이 있습니까? 정수가 경고없이 오버플로되는 것이 여전히 정확합니까? 오늘 파일을 처리하고 오류 발생시 파일 닫기를 처리하기 위해 상용구를 작성할 필요없이 파일을 처리하는 방법이 있습니까?
안드레아

@Andrea 나는 대답을 편집했다.
coredump

1
"... Lisp의 숫자 탑 대신에 그것을 선호하는 사람들이 있습니다. (왜 그런지 모르겠습니다.) 이것이 형식 유추에 도움이 될 것 같습니다." 빙고. SML 및 OCaml 유형 시스템에서는 모든 표현식에 하나의 유형 만 있어야합니다. SML의 수학 연산자 오버로드는 언어에 내장 된 예외입니다. Haskell도 마찬가지입니다. 이런 종류의 오버로드를 가능하게하는 것은 유형 클래스의 동기였습니다. 캐치는 유형마다 하나의 유형 클래스 인스턴스 만 가질 수 있다는 것입니다. 또한 맹목적으로 정수를 같은 크기의 부동 소수점으로 변환 할 수 없습니다. 64 비트 부동 소수점은 54 비트의 정밀도 만 갖습니다.
Doval

@Doval Racket에 숫자 타워입력하는 것과 같은 것은 어떻습니까? 다형성 수학 연산자를 제공하기 위해 타입 클래스 또는 GADT (Generalized Algebraic Data Types)를 이용하는 OCaml 라이브러리를 상상할 수 있습니까? 변환 관련 : 모든 작업이 가능하지는 않지만 일부는 입력 가능합니다.
coredump

2
@Doval : "Re : 다형성 수학 연산자, Haskell의 타입 클래스를 구현하지 않으면 어떤 방법도 없다고 생각합니다." F #에는 형식 클래스가없는 다형성 수학 연산자가 있습니다.
Jon Harrop

7

아주 오래된 페이지 (2007) 인 것을보고 : 현재 어떤 글 머리 기호가 여전히 유효한가?

  • 잘못된 보안 감각 . 이것은 말도 안됩니다.

  • 몇 가지 기본 유형 . OCaml에는 바이트 및 바이트 배열이 있지만 기본 제공 유니 코드 문자열, 16 비트 정수, 부호없는 정수, 32 비트 부동 소수점, 벡터 또는 행렬은 없습니다. 타사 라이브러리는 이들 중 일부를 제공합니다.

  • 자동 정수 오버플로 . 변경되지 않았지만 결코 문제가되지 않았습니다.

  • 모듈 불변성 . 함수와 모듈이 변경 가능해야한다는 그의 추천은 Lisp에 대한 심각한 후퇴와 정말 나쁜 생각입니다. include원하는 경우 사용하여 모듈을 대체 할 수 있지만 물론 변경할 수는 없습니다.

  • 다형성으로 인해 런타임 유형 오류가 발생 합니다. 이것은 OCaml의 큰 문제이며 해결되지 않았습니다. 유형이 다형성 평등을 발전함에 따라 함수와 같은 유형을 발견하고 문제를 디버깅하는 것은 비교 및 ​​해싱이 실패하기 시작합니다. F #에는이 문제에 대한 훌륭한 해결책이 있습니다.

  • 매크로 없음 . 아이러니하게도,이 OCaml을 작성할 때 실제로 매크로를 완전히 지원했지만 이제는 기능을 꺼내기로 결정했습니다.

  • 포장지 . 이것은 실제 문제였으며 해결되지 않았습니다. 여전히 try ... finallyOCaml 언어 에는 구성이없고 stdlib에는이를 구현하는 래퍼가 없습니다.

  • 장소 . 변경되지 않았지만 문제가 아닙니다.

  • 필드 명명 지옥을 기록하십시오 . 모듈을 사용하여 코드를 올바르게 구성하십시오.

  • 구문 . 변경되지 않았지만 문제가 아닙니다.

  • 다형성 없음 . 그가 썼을 때 이것은 대부분 넌센스였으며 아무것도 바뀌지 않았습니다.

  • 일치하지 않는 기능 세트 . OCaml에는 여전히 cons기능 이 없습니다 . 괜찮아. 언어로 된 리스프를 원하지 않습니다. 감사합니다.

  • 동적 변수가 없습니다 . OCaml에 대해 좋은 일이었습니다. 여전히 OCaml에 대해 좋은 것입니다.

  • 선택적 ~ 인수 suck . 선택적인 주장은 흔들린다. F #에 선택적 인수를 추가하도록 Microsoft에 기장했습니다.

  • 부분 인수 응용 프로그램 불일치 . 뭐라고?

  • 산술의 가독성 . ~ 8 년 전 OCaml 사용을 중단 한 이후로 변경되었습니다. 분명히 당신은 할 수 있습니다 Int64.((q * n - s * s) / (n - 1L)).

  • 자동 이름 충돌 해결 . 그는 Lisp에서와 마찬가지로 REPL에서 본격적인 소프트웨어 개발을 시도했습니다. OCaml에서는 그렇게하지 마십시오. 테스트, 일회용 코드 실행 및 대화식 기술 컴퓨팅을 위해서만 REPL을 사용하는 파일 및 배치 컴파일을 사용하십시오.

  • 평가 순서 . 그가 썼을 때 이것은 잘못되었습니다. 평가 순서는 OCaml에 정의되어 있지 않습니다.

  • 객체 입 / 출력이 없습니다 . 그는 이미이 "문제"를 해결 한 타사 라이브러리를 인용했습니다.

  • 첫 번째 오류 후에 컴파일러가 중지됩니다 . 뭐라고?

  • 기본적으로 컴파일 된 실행 파일에 대한 스택 추적이 없습니다 . 결정된.

  • 디버거가 짜증 난다 . 나는 디버거를 사용한 적이 없다. 정적 유형 검사는 거의 모든 버그를 잡아냅니다.

  • GC는 짜증나 . OCaml의 GC가 한 가지 큰 문제를 제외하고는 훌륭하다는 것을 알았습니다. 전역 잠금은 병렬 프로그래밍을 방지합니다.

  • 암시 적 전달 선언이 없습니다 . 상호 재귀는 모든 ML에서 설계 상 명시 적입니다. 유일한 예외는 type정의가 기본적으로 재귀 적이지만 let바인딩은 기본적 으로 비 재귀 적이라는 것입니다.

  • 함수 라운드가 없습니다 . OCaml에는 여전히 뼈대 stdlib가 있지만 Jane St 's Core와 같은 타사 라이브러리가 제공 round하고 친구가 있습니다.

  • 목록 . List.map여전히 꼬리 재귀가 아닙니다. 나는 이와 같은 심각한 버그를 수정하기 위해 패치를 제출했으며 릴리스에 나타나기까지 몇 년을 기다려야했습니다. 물론 목록은 여전히 ​​불변입니다. 그래서 그들은해야합니다.

  • 속도 . 큰 다형성 변형에 대한 컴파일 시간이 수정되었다고 생각합니다.

  • 패턴 매칭 . 현실에 대한 희망의 승리. Lisp 커뮤니티는이를 수행하지 못했습니다. 따라서 제 10 번째 규칙 : 충분히 복잡한 Lisp 프로그램에는 OCaml의 패턴 일치 컴파일러의 절반에 대한 비공식적으로 지정되고 버그에 의해 작성된 임시 구현이 포함됩니다.

예를 들어 : 일반 객체를 인쇄 할 수 없다는 것이 여전히 사실입니까?

그가 당신이 단순히 할 수 없다고 썼을 때 :

print value

그러나 최상위 수준에서 라이브러리 호출로 pretty printer를 호출하여 필요한 유형 정보를 제공 할 수 있습니다. 그리고 예쁜 프린터를 자동 생성하기 위해 데이터 구조에 주석을 달 때 사용할 수있는 매크로가있었습니다.


패턴 매칭 : OCaml 소스 코드옵티마 는 "패턴 매칭 최적화"라는 동일한 논문을 참조합니다. 여기서는 "임시", "버그 지정"또는 "비공식적으로 지정된"어느 것도 실제로 적용 할 수 없다고 말하고 싶습니다. "F #에는이 문제에 대한 훌륭한 해결책이 있습니다.": 가능하면 이에 대해 좀 더 자세히 알고 싶습니다. 대답은 좋지만 이야기 할 때 저주 cons가 나쁜 톤을줍니다 (원본 기사는 맹세하지만 그것을 복사 할 필요는 없습니다).
coredump

2
@coredump : "가능한 경우 이것에 대해 좀 더 자세히 알고 싶습니다." F #에는 특정 연산자 및 함수에 대해 사용자 정의 임시 다형성이 있습니다. 따라서 +int, float 및 complex에 사용할 수 있지만 고유 한 유형을 정의하고 해당 유형에 대한 +작업을 위해 과부하를 추가 할 수도 있습니다 . 이는 Lisp 또는 Haskell의 간결성과 가독성을 통해 SML 또는 OCaml의 우수한 성능을 예측할 수 있으며 다른 언어로는 할 수없는 것을 달성합니다.
Jon Harrop

@coredump : "OCaml 소스 코드와 옵티마는 모두 동일한 논문을 참조합니다". 이 문서에서 설명하는 기술은 전적으로 ML 유형 시스템을 기반으로합니다. Lisp에없는 타입 시스템. 옵티마는 그 논문에 기술 된 내용을 많이하지 않으며 할 수 없습니다. 섹션 4.2 "전체 정보 사용"을 참조하십시오. 변형 유형이 없기 때문에 Lisp에는 완전한 정보가 없습니다. 예를 들어, OCaml은 잎 수에 따라 중첩 된 점프 또는 디스패치 테이블 중에서 선택하지만 해당 정보는 Lisp에서 알 수 없습니다.
Jon Harrop

Lisp와 OCaml은 다른 것들 (예를 들어, 역 동성, 이미지 기반 프로그래밍)을 위해 설계되었습니다. 그러나 Lisp Hindley-Milner와 다른 유형 시스템을 가지고 있으며 구현 시 컴파일시 이를 활용합니다. 이 SBCL 세션에서이 문서의 4.2 섹션에있는 예제를 살펴보십시오 . Exhaustiveness는 컴파일러가 형식 유추 및 선언에서 이미 확인했습니다. Optima는 컴파일 타임 매크로 확장 (또는 SBCL VOP)을위한 구현 별 코드를 추가하여 다른 전략을 수립 할 수는 있지만 인센티브가 충분하지 않습니다.
coredump

이는 사용자 정의 대수 데이터 유형에 어떻게 적용됩니까?
Jon Harrop
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.