[C#] C #보다 F #을 사용하는 것이 어떤 영역에서 더 적합 할 수 있습니까? [닫은]

지난 몇 년 동안 F #은 OCaml, ML 및 Haskell에서 배양 된 많은 아이디어를 사용하여 Microsoft의 완벽하게 지원되는 언어 중 하나로 발전했습니다.

지난 몇 년 동안 C #은 점점 더 기능적인 언어 기능인 LINQ (목록 이해), Lambdas, 폐쇄, 익명 대표 등을 도입하여 범용 기능을 확장했습니다.

C #에서 이러한 기능적 기능을 채택하고 F #의 분류를 불완전한 기능적 언어로 가정하면 (필요한 경우 함수를 호출 할 때 프레임 워크 라이브러리에 액세스하거나 공유 상태를 변경할 수 있음) 두 언어 간에는 유사성이 있습니다. 자신의 극성 반대 주요 강조.

프로덕션 폴리 글 로트 프로그램에서이 두 가지 언어를 사용하는 성공적인 모델과 작년에 F #으로 작성된 프로덕션 소프트웨어 (웹 앱, 클라이언트 앱, 서버 앱) 영역에 관심이 있습니다. C #으로 작성되었습니다.



답변

발전소 포트폴리오의 국가 발전 일정과 에너지 회사의 거래 위치 간의 균형을 맞추기위한 신청서를 작성했습니다. 클라이언트 및 서버 구성 요소는 C #에 있지만 계산 엔진은 F #에 작성되었습니다.

이 응용 프로그램의 핵심 인 복잡성을 해결하기 위해 F #을 사용하면 엔터프라이즈 소프트웨어 내에서 언어에 대한 유용한 지점, 즉 대규모 데이터 세트의 알고리즘 적으로 복잡한 분석이 명확하게 나타납니다. 내 경험은 매우 긍정적이었습니다. 특히:

측정 단위 내가 일하는 산업은 단위로 가득 차 있습니다. 내가 구현 한 방정식 (종종 기하학적 특성)은 시간, 전력 및 에너지 단위를 처리했습니다. 타입 시스템이 함수의 입력 및 출력 단위의 정확성을 검증하도록하는 것은 코드 테스트 및 읽기 / 이해 측면에서 엄청난 시간 절약입니다. 이전 시스템에서 발생하기 쉬운 전체 클래스의 오류를 제거합니다.

탐색 프로그래밍 스크립트 파일 및 REPL (F # Interactive)을 사용하면 기존의 편집 / 컴파일 / 실행 / 테스트 루프보다 구현을 커밋하기 전에 솔루션 공간을보다 효과적으로 탐색 할 수있었습니다. 프로그래머가 문제와 디자인 장력에 대한 이해를 쌓는 것은 매우 자연스러운 방법입니다.

비 효과적인 기능과 불변의 데이터 구조를 사용하여 작성된 코드 테스트 는 테스트의 즐거움입니다. 복잡한 시간 의존적 상호 작용이 없어서 조롱해야 할 많은 의존성이나 문제를 해결할 수 있습니다.

상호 운용성 C #에서 계산 엔진에 대한 인터페이스를 정의하고 F #에서 계산을 구현했습니다. 그런 다음 상호 운용성에 대해 전혀 염려하지 않고 계산 엔진을 사용해야하는 모든 C # 모듈에 계산 엔진을 삽입 할 수 있습니다. 원활한. C # 프로그래머는 알 필요가 없습니다.

코드 축소 계산 엔진에 공급 된 대부분의 데이터는 벡터와 행렬의 형태였습니다. 고차 함수는 최소한의 소란, 최소한의 코드로 아침 식사를 위해 이것을 먹습니다. 아름다운.

버그 부족 기능 프로그래밍이 이상하게 느껴질 수 있습니다. 알고리즘을 작업하면서 코드가 형식 검사기를 통과하도록 열심히 노력하고 있지만 유형 검사기가 만족하면 작동합니다. 거의 바이너리이거나 컴파일되지 않거나 올바른 것입니다. 이상한 대소 문자 오류가 최소화되고 재귀 및 고차 함수로 인해 대소 문자 오류가 발생하는 많은 장부 코드가 제거됩니다.

병렬 처리 결과 구현의 기능적 순도는 데이터 벡터 처리에서 고유 한 병렬 처리를 활용하기에 적합합니다. .NET 4가 나오기 때문에 다음에 갈 곳입니다.


답변

Microsoft Research에서 인턴으로 근무하는 동안 Visual Studio IntelliSense for F # (F #으로 작성)의 일부를 작업했습니다. 이전 C # 프로젝트의 IntelliSense에 대한 경험이 이미 있었으므로 두 가지를 비교할 수 있다고 생각합니다.

  • Visual Studio Extensibility는 여전히 COM을 기반으로하므로 .NET 개체가 아닌 (그리고 기능이없는) 개체를 처리해야하지만 C #과 F #간에 큰 차이가 없다고 생각합니다 (매끄럽게 작동 함). F #에서)

  • F #에서 프로그램 코드를 나타내는 데 사용되는 데이터 구조는 대부분 차별 된 공용체 (C #에서는 합리적인 방식으로 지원되지 않음)이며 이런 종류의 응용 프로그램 (프로그램 코드와 같은 트리 구조를 처리해야하는 경우)에 차이가 있습니다. ). 식별 된 공용체 및 패턴 일치를 사용하면 코드를보다 잘 구성 할 수 있습니다 (가상 메서드에서 모든 기능을 사용하지 않고 한 곳에서 관련 기능 유지)

이전에는 F # 용 CodeDOM 공급자 (F #로도 작성)에서 근무했습니다. 실제로 C #에서 처음 실험을했지만 코드를 F #으로 변환했습니다.

  • CodeDOM 공급자는 .NET 객체를 사용하여 표현 된 일부 구조를 통과해야하므로 고유 한 데이터 표현 (F #이 좋은 이점을 제공 할 수있는 영역)을 발명 할 공간이 없습니다.

  • 그러나 작업을보다 쉽게하는 작은 F # 기능이 많이있었습니다. 문자열을 생성해야하기 때문에 문자열을 작성하기위한 사용자 정의 연산자를 정의 StringBuilder하고 (을 사용하여 ) 문자열을 사용 하여 코드를 구현하고 높은 수준의 함수 (예 : 지정된 문자열을 사용하여 분리 된 객체 목록의 형식을 지정하는 등)를 많이 수행했습니다. 반복 (그리고 지루한 foreach루프).

이들은 상대적으로 구체적인 두 가지 예이지만 둘 다 프로그램 표현이나 표현 또는보다 일반적으로 복잡한 트리 형 데이터 구조 작업과 관련이 있습니다. 이 영역에서는 F #이 C #의 기능적 기능에 관계없이 확실히 좋은 선택이라고 생각합니다.


답변

F # ( F # for Visualization ) 및 두 번째 ( F # for Numerics )로 작성된 세계 최초의 상용 제품 과 F # ( The F # .NET Journal ) 에 대한 최초의 상업적 문헌을 제공 하고 현재 버전에 대한 유일한 책을 작성하고 출판했습니다. of F # ( 기술 컴퓨팅을위한 Visual F # 2010 ).

우리는 C #으로 작성된 비슷한 라인을 따라 제품을 운송하고 있었지만 (예 : this ) OCaml의 상업적 사용에 대한 배경 지식도 풍부했습니다. 우리는 F #이 2006 년에도 여전히 연구 프로토 타입이었을 때 F #을 적극적으로 채택했습니다. 우리는 산업 수준의 .NET 플랫폼에서 현대적인 OCaml과 유사한 언어를 사용할 가능성을 인식하고 제품화를 추진했습니다. 그 결과 놀라운 성공을 거두었고 F #은 우리의 기대에 훨씬 못 미쳤습니다.

우리에게 F #에는 여러 가지 장점이 있으며 다양한 용도로 사용합니다. 프로덕션 환경에는 수십만 줄의 F # 코드가 있습니다. 이제 모든 LOB 앱에 F #을 사용 합니다. 신용 카드 거래는 F # 코드를 사용하여 처리되고, 제품 알림은 F # 코드를 사용하여 전송되며, 구독은 F # 코드를 사용하여 처리되며, 계정은 F # 코드를 사용하여 수행됩니다. 아마도 여기서 배당금을 지불하는 주요 언어 기능은 패턴 일치입니다. 우리는 심지어 F #을 사용하여 최신 책을 강조하는 색 구문을 사용했습니다 …

우리의 시각화 라이브러리는 큰 판매자이며 그 기능은 Visual Studio에서 실행되는 F # 대화식의 중심입니다. 라이브러리는 최소한의 노력으로 대화 형 2D 및 3D 시각화를 생성하는 기능으로이를 보완합니다 (예 :Plot([Function sin], (-6., 6.))사인파를 그릴 수 있습니다). 특히 모든 스레딩 문제는 완전히 자동화되므로 사용자는 UI 스레드 및 디스패치에 대해 걱정할 필요가 없습니다. 라이브러리의이 부분을 작성할 때 일류 함수와 게으름은 매우 중요했으며 대수 데이터 유형은 다른 곳에서 광범위하게 사용되었습니다. 고객이 WPF의 적중 테스트에서 성능 버그를 발견하고 F #에서 관련 코드를 쉽게 다시 구현하여 10,000 배의 성능을 개선 할 수있을 때 예측 가능한 성능도 가치가있는 것으로 입증되었습니다. 이 제품 GUI의 자유 형식으로 인해 GUI 디자이너와 C #은 도움이되지 않았습니다.

대부분의 작업은 상용 라이브러리와 서적을 포함한 수치 적 방법에 중점을두고 있습니다. F #은 최소한의 성능 저하로 높은 수준의 추상화 (예 : 고차 함수)를 제공하기 때문에 C #보다이 영역에서 훨씬 더 강력합니다. 이러한 맥락에서 가장 주목할만한 결과는 선형 대수에서 QR 분해의 단순하지만 일반화 된 구현을 생성 한 것으로, LAPACK 참조 구현의 Fortran 코드보다 20 배 더 짧으며 공급 업체가 조정 한 Intel Math보다 최대 3 배 더 빠릅니다. 코드가 모든 유형의 행렬, 심지어 기호 형 행렬을 처리 할 수 ​​있기 때문에 커널 라이브러리 및보다 일반적입니다!

우리는 현재 소프트웨어 제품에 대한 대화식 매뉴얼 역할을하는 WPF 앱을 구축하는 F # (내장 용) 및 C # (심용)의 혼합으로 WPF / Silverlight 구성 요소를 개발하고 있으며 새 책인 Multicore F #를 작성하고 있습니다. .NET에서 공유 메모리 병렬 프로그래밍에 대한 확실한 안내서가 될 것입니다.


답변

지난 6 개월 동안 저는 Visual Studio 2010 용 Vim 에뮬레이션 레이어에서 작업 해 왔습니다. github에서 무료로 사용할 수있는 모든 소스를 갖춘 무료 제품입니다.

이 프로젝트는 별개의 레이어를 나타내는 3 개의 DLL로 나뉩니다. 각 레이어에는 해당 단위 테스트 dll이 있습니다.

  1. Vim 엔진 : F #
  2. 장식 및 편집기 통합을위한 WPF 계층 : C #
  3. Visual Studio 통합 계층 : C #

이것은 내가 F #으로 한 첫 번째 주요 프로젝트이며 언어를 좋아한다고 말해야합니다. 여러 가지 방법으로이 프로젝트를 F # 학습 방법으로 사용했습니다 (이 학습 곡선은 프로젝트 기록을 살펴보면 매우 분명합니다).

F #에서 가장 놀라운 점은 언어의 간결함입니다. Vim 엔진은 대부분의 로직을 구성하지만 전체 코드베이스의 30 % 만 포함합니다.


답변

F # Visual Studio 구성 요소에 대한 많은 단위 테스트가 F #으로 작성되었습니다. VS 외부에서 실행되어 다양한 Visual Studio 비트를 조롱합니다. 인터페이스를 구현하는 익명 객체를 구성하는 기능은 조롱 프레임 워크 / 도구 대신 유용합니다. 그냥 쓸 수 있어요

let owpe : string list ref = ref []
let vsOutputWindowPane =
    { new IVsOutputWindowPane with
        member this.Activate () = err(__LINE__)
        member this.Clear () = owpe := []; 0
        member this.FlushToTaskList () = VSConstants.S_OK
        member this.GetName(pbstrPaneName) = err(__LINE__)
        member this.Hide () = err(__LINE__)
        member this.OutputString(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputStringThreadSafe(pszOutputString) = owpe := pszOutputString :: !owpe ; 0
        member this.OutputTaskItemString(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText) = err(__LINE__)
        member this.OutputTaskItemStringEx(pszOutputString, nPriority, nCategory, pszSubcategory, nBitmap, pszFilename, nLineNum, pszTaskItemText, pszLookupKwd) = err(__LINE__)
        member this.SetName(pszPaneName) = err(__LINE__)
    }
DoSomethingThatNeedsA(vsOutputWindowPane)
assert( !owpe = expectedOutputStringList )

나는를 예의 인스턴스를 필요로 할 때 IVsOutputWindowPane결국 호출됩니다 다른 구성 요소에 전달 OutputString하고 Clear, 다음 검사 string list ref예상 출력이 작성되었는지 확인하기 위해 테스트의 마지막 개체를.


답변

F #에서 Lex-Yacc 구현을 사용하여 사용자 지정 규칙 엔진 언어를 작성했습니다.

댓글 답글을 포함하도록 수정

C #에는 lex / yacc 구현이 없습니다. (우리가 알고있는 한, F # 하나는)

파싱 ​​자체를 구축하는 것은 가능하지만 명백한 고통입니다.

이 주제 에서는 외부 라이브러리와 같은 다른 제안을 보여 주지만, 우리의 수석 아키텍트는 기능적 언어를 사용하는 숙련자이므로 F #을 사용하는 것은 쉬운 일이 아닙니다.


답변

현재 프로그래밍 언어에 대한 컴파일 작업 중입니다. 컴파일러는 전적으로 F #으로 작성됩니다. 컴파일러 (lex / yacc를 사용한 lex 및 파서 빌드 제외)는 기본적으로 구조와 같은 복잡한 트리의 많은 변환으로 빌드됩니다.

다른 사람들이 지적한 바와 같이, 차별적 인 노조와 패턴 매칭은 이런 종류의 데이터 구조로 작업하는 것이 가상 방법으로 코드를 “모든 곳에서”덤프하는 것보다 훨씬 쉽다

컴파일러 작업을 시작하기 전에 F # 작업을 수행하지 않았습니다. (하지만 MoscowML이라는 다른 OCaml 변형의 컴파일러를 만들었습니다) Jared가 말했듯이 코드에서 처음으로 수행 한 부분을 볼 수 있지만 일반적으로 F #을 쉽게 발견했습니다. 10 년 동안 주로 OO를 코딩 한 후 FP 마인드에 다시 들어가는 법을 배우는 데는 시간이 조금 더 걸립니다.

트리를 제외하고는 선언적 코드를 작성하는 기능이 알고리즘을 설명하는 코드를 갖는 FP (F # 포함)의 주요 이점을 발견했습니다. 알고리즘을 구현 한 방법을 설명 하는 C #과 달리 구현하려고하는 것은 큰 이점입니다.