“브루 브 역설”과 C ++ 기능이나 관용구가 있습니까? 특히이 인용문은 내

나는 여기에 기사를 읽고 있었다 : http://www.paulgraham.com/avg.html “blub paradox”에 관한 부분은 특히 흥미로웠다. 주로 C ++로 코딩하지만 다른 언어 (주로 Haskell)에 노출 된 사람으로서 나는이 언어에서 C ++로 복제하기 어려운 몇 가지 유용한 것을 알고 있습니다. 문제는 주로 c ++와 다른 언어에 능숙한 사람들에게 있습니다. c ++로만 작성하는 경우 개념화하거나 구현하기 어려운 언어에서 사용하는 강력한 언어 기능이나 관용구가 있습니까?

특히이 인용문은 내 관심을 끌었습니다.

귀납적으로, 다양한 언어들 사이의 모든 힘의 차이를 볼 수있는 유일한 프로그래머는 가장 강력한 언어를 이해하는 사람들입니다. (이것은 아마도 Eric Raymond가 Lisp가 당신을 더 나은 프로그래머로 만드는 것에 대한 의미 일 것입니다.) Blub 역설 때문에 다른 사람들의 의견을 믿을 수는 없습니다. Blub 역설 때문에 그들은 사용하는 언어에 만족합니다. 그들이 프로그램에 대해 생각하는 방식.

c ++를 사용하여 “Blub”프로그래머와 동등한 것으로 밝혀지면 다음과 같은 질문이 발생합니다. 다른 언어에서 경험 한 개념이나 기술이 있습니까? C ++에서 쓰거나 “생각”했습니까?

예를 들어 Prolog 및 Mercury와 같은 언어에서 볼 수있는 논리 프로그래밍 패러다임은 캐스터 라이브러리를 사용하여 c ++로 구현할 수 있지만 궁극적으로 Prolog 코드 측면에서 생각하고이를 사용할 때 C ++로 변환한다는 것을 알았습니다. 내 프로그래밍 지식을 넓히는 방법으로 c ++ 개발자로 알지 못하는 다른 언어로보다 효율적으로 표현되는 유용하고 강력한 관용구의 다른 유사한 예가 있는지 알아 내려고 노력 중입니다. 염두에 두어야 할 또 다른 예는 lisp의 매크로 시스템입니다. 프로그램 내에서 프로그램 코드를 생성하면 일부 문제에 많은 이점이있는 것 같습니다. 이것은 C ++ 내에서 구현하고 생각하기 어려운 것 같습니다.

이 질문은 “c ++ vs lisp”토론 또는 어떤 종류의 언어 전쟁 유형 토론이 아닙니다. 이와 같은 질문을하는 것은 내가 모르는 것에 대해 알 수있는 유일한 방법입니다.



답변

하스켈을 언급 한 이후 :

  1. 패턴 매칭. 읽고 쓰기가 훨씬 쉬운 패턴 일치를 찾습니다. 맵의 정의를 고려하고 패턴 일치없이 언어로 구현되는 방법에 대해 생각하십시오.

    map :: (a -> b) -> [a] -> [b]
    map f [] = []
    map f (x:xs) = f x : map f xs
  2. 타입 시스템. 때때로 고통이 될 수 있지만 매우 도움이됩니다. 실제로 이해하고 잡는 버그의 수를 이해하려면 프로그래밍해야합니다. 또한, 참조 투명성은 훌륭합니다. 명령형 언어로 상태를 관리함으로써 몇 개의 버그가 발생했는지 Haskell에서 프로그래밍 한 후에야 분명해집니다.

  3. 일반적인 기능 프로그래밍. 반복 대신 맵과 접기를 사용합니다. 재귀. 더 높은 수준의 사고에 관한 것입니다.

  4. 게으른 평가. 다시 한 번 더 높은 수준으로 생각하고 시스템이 평가를 처리하도록하는 것입니다.

  5. 오두막, 패키지 및 모듈. Cabal 다운로드 패키지가 있으면 소스 코드를 찾거나 makefile을 작성하는 것보다 훨씬 편리합니다. 특정 이름 만 가져올 수있는 것이 기본적으로 모든 소스 파일을 함께 덤프 한 다음 컴파일하는 것보다 훨씬 좋습니다.


답변

기억하세요!

C ++로 작성해보십시오. C ++ 0x에는 해당 되지 않습니다 .

너무 성가 시나요? 좋아, 그것을 시도 C ++ 0X.

D에서이 4 라인 (또는 5 라인, : P) 컴파일 타임 버전을 이길 수 있는지 확인하십시오 .

auto memoize(alias Fn, T...)(T args) {
    auto key = tuple(args);                               //Key is all the args
    static typeof(Fn(args))[typeof(key)] cache;           //Hashtable!
    return key in cache ? cache[key] : (cache[key] = Fn(args));
}

그것을 호출하기 위해해야 ​​할 일은 다음과 같습니다.

int fib(int n) { return n > 1 ? memoize!(fib)(n - 1) + memoize!(fib)(n - 2) : 1;}
fib(60);

Scheme에서 비슷한 것을 시도 할 수도 있습니다. 런타임에서 발생하기 때문에 여기에서 조회가 해시 대신 선형 적이기 때문에 (그리고 Scheme이기 때문에) 조금 느립니다.

(define (memoize f)
    (let ((table (list)))
        (lambda args
            (cdr
                (or (assoc args table)
                    (let ((entry (cons args (apply f args))))
                        (set! table (cons entry table))
                        entry))))))
(define (fib n)
        (if (<= n 1)
            1
            (+ (fib (1- n))
                (fib (- n 2)))))))
(set! fib (memoize fib))


답변

C ++은 다중 패러다임 언어이므로 여러 가지 사고 방식을 지원하려고합니다. 함수형 프로그래밍의 경우처럼 C ++ 기능이 다른 언어의 구현보다 더 어색하거나 덜 유창한 경우가 있습니다.

즉, yieldPython 또는 JavaScript에서 수행하는 기본 C ++ 언어 기능의 머리 꼭대기를 생각할 수는 없습니다 .

또 다른 예는 동시 프로그래밍 입니다. C ++ 0x는 그것에 대해 말할 것이지만 현재 표준은 그렇지 않으며 동시성은 완전히 새로운 사고 방식입니다.

또한 C ++ 프로그래밍 영역을 떠나지 않으면 빠른 개발 (쉘 프로그래밍)조차도 배우지 못할 것입니다.


답변

코 루틴 은 C ++에 비해 다른 언어의 많은 실질적인 이점을 뒷받침하는 매우 유용한 언어 기능입니다. 기본적으로 추가 스택을 제공하므로 기능을 중단하고 계속할 수 있으므로 필터를 통해 작업 결과를 다른 작업에 쉽게 제공하는 언어에 파이프 라인과 유사한 기능을 제공합니다. 훌륭합니다. Ruby에서는 매우 직관적이고 우아했습니다. 게으른 평가도 이것과 관련이 있습니다.

C ++에없는 강력한 기능은 무엇이든 내부 검사 및 런타임 코드 컴파일 / 실행 / 평가 / 무엇입니까?


답변

Lisp와 C ++ 모두에서 컴퓨터 대수 시스템을 구현 한 후에는 언어에 대한 완전한 초보자 였지만 Lisp에서 작업이 훨씬 쉬웠다 고 말할 수 있습니다. 목록에있는 모든 것의 단순한 특성으로 인해 많은 알고리즘이 단순화됩니다. 물론 C ++ 버전은 수십 배 더 빨랐습니다. 그래, lisp 버전을 더 빨리 만들 수는 있었지만 코드는 lispy만큼 좋지 않을 것입니다. 예를 들어 스크립팅은 항상 더 쉬워 질 것입니다. 작업에 적합한 도구를 사용하는 것이 전부입니다.


답변

한 언어가 다른 언어보다 “더 강력하다”고 할 때 무엇을 의미합니까? 언어가 “표현 적”이라고 말할 때 아니면 “부자?” 나는 생각 아니, 정말 상태 전이 – 우리는 시야각이 충분히 좁아 언어 이익 전원이 쉽고 자연의 문제를 설명 할 수 있도록 의미? -그것은 그 견해 안에 있습니다. 그러나 그 언어는 우리의 시야가 넓어 질 때 상당히 덜 강력하고 표현력이 떨어지며 유용하지 않습니다.

언어가 “강력하고”표현이 많을수록 사용이 제한됩니다. 따라서 “강력한”및 “표현 적”은 좁은 유틸리티 도구에 사용하는 잘못된 단어 일 수 있습니다. 어쩌면 “적절한”또는 “추상적 인”이 그러한 것들에 대한 더 나은 단어 일 것입니다.

나는 저수준의 많은 것들을 작성함으로써 프로그래밍을 시작했다 : 인터럽트 루틴을 가진 장치 드라이버; 임베디드 프로그램; 운영 체제 코드. 코드는 하드웨어와 밀접한 관계가 있으며 어셈블리 언어로 모두 작성했습니다. 우리는 어셈블러가 가장 추상적이지 않다고 말하지는 않았지만 어셈블러는 가장 강력하고 표현력이 뛰어난 언어였습니다. 어셈블리 언어로 문제를 표현할 수 있습니다. 어떤 기계로든 내가 원하는 것을 할 수있을만큼 강력합니다.

그리고 나중에 고급 언어에 대한 모든 이해는 어셈블러에 대한 모든 경험으로 인해 발생합니다. 나중에 배운 모든 것은 쉬웠습니다. 왜냐하면 아무리 추상적이더라도 결국에는 하드웨어 자체를 수용해야하기 때문입니다.

더 높고 높은 추상화 수준, 즉 좁고 좁은 시야를 잊고 싶을 수도 있습니다. 나중에 언제든지 선택할 수 있습니다. 며칠 만에 배우는 것은 간단합니다. 내 의견으로는 하드웨어 1 의 언어를 배우고 뼈에 최대한 가까이 접근하는 것이 더 나을 것 입니다.


1 아마도 아주 밀접한 관계가 아니지만, carcdr하드웨어에서 자신의 이름을 : 첫 번째 리스프 실제 감소시킵니다 등록 및 실제 주소 등록을 한 컴퓨터에서 실행. 어때요?


답변

연관 배열

데이터를 처리하는 일반적인 방법은 다음과 같습니다.

  • 입력을 읽고 그로부터 계층 구조를 구성합니다.
  • 해당 구조에 대한 색인 작성 (예 : 다른 순서)
  • 그들의 추출물 (필터링 된 부분)을 생성하고,
  • 값 또는 값 그룹 찾기 (노드)
  • 구조를 다시 정렬합니다 (노드 삭제, 규칙에 따라 하위 요소 추가, 추가, 제거 등).
  • 나무를 통해 스캔하여 인쇄하거나 일부를 저장하십시오.

이를위한 올바른 도구는 연관 배열 입니다.

  • 내가 본 연관 배열에 대한 최상의 언어 지원은 MUMPS입니다 . 연관 배열은 다음과 같습니다. 1. 항상 정렬 됨 2. 동일한 구문을 사용하여 디스크 (소위 데이터베이스)에서 만들 수 있습니다. (부작용 : 데이터베이스로서 매우 강력하며, 프로그래머는 네이티브 btree에 액세스 할 수 있습니다. 최고의 NoSQL 시스템입니다.)
  • 내 두 번째상은 PHP에 간다 . 나는 $ a [] = x 또는 $ a [x] [y] [z] ++ 와 같은 foreach 와 쉬운 구문을 좋아한다 .

JavaScript의 연관 배열 구문이 마음에 들지 않습니다. 왜냐하면 a [x] [y] [z] = 8을 만들 수 없기 때문에 먼저 a [x]a [x] [y] 를 만들어야 합니다 .

좋아, C ++ (및 Java)에는 컨테이너 클래스, Map , Multimap 등 의 훌륭한 포트폴리오가 있지만 스캔하고 싶다면 반복자를 만들어야하며 새로운 심층 요소를 삽입 할 때 모든 상위 레벨 등을 작성해야합니다. 불편합니다.

C ++ (및 Java)에는 사용할 수있는 연관 배열이 없지만 유형이없는 (또는 엄격하지 않은 유형의) 스크립트 언어는 유형이없는 스크립트 언어이기 때문에 컴파일 된 언어를 능가합니다.

면책 조항 : C # 및 기타 .NET 언어에 익숙하지 않습니다 .AFAIK에는 우수한 연관 배열 처리 기능이 있습니다.