ProgramingTip

Scala 2.8 컬렉션 라이브러리는 "역사상 가장 긴 자살 기록"의 사례입니까?

bestdevel 2020. 9. 28. 09:40
반응형

Scala 2.8 컬렉션 라이브러리는 "역사상 가장 긴 자살 기록"의 사례입니까? [닫은]


나는 임박한 2.8 릴리스 에서 제공 될 Scala 컬렉션 라이브러리 재 구현에 대해 방금 살펴보기 시작 했습니다 . 2.7의 라이브러리에 익숙한 사용자는 사용에서 거의 변경되지 않습니다. 예를 들면 ...

> List("Paris", "London").map(_.length)
res0: List[Int] List(5, 6)

... 두 버전 모두에서 작동합니다. 라이브러리는 매우 유용합니다 . 사실 환상적입니다. 그러나 이전에 Scala에 익숙하지 않은 사고 고 언어에 대한 느낌을 얻으려면 이제 다음과 같은 방법을 이해해야합니다.

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

단지 단순한 기능의 경우 벅찬 시그니처이며 제가 이해하기 힘든 시그니처입니다. 저는 Scala가 다음 자바 (또는 / C / C ++ / C #) 가 될 가능성 이 있습니다.하지만 Scala가 될 가능성이 있다고 생각합니다. 다음 Ruby 또는 Python (즉, 상당한 상업적 사용자 기반 확보)

  • 이로 인해 사람들이 스칼라로 오는 것을 방해할까요?
  • 상업 세계에서 이것이 스칼라를 헌신적 인 박사 과정 학생들 만 이해할 수 있는 학문적 장난감 으로 나쁜 이름으로 만들까요? 있습니까 CTO 의 및 소프트웨어의 머리는 겁받을 것 ?
  • 도서관 재 설계가 현명한 아이디어였습니까?
  • Scala를 상업적으로 사용하고 권한에 대해 걱정하십니까? 2.8을 즉시 채택 할 계획입니까, 아니면 어떤 일이 발생하는지 기다릴 계획입니까?

Steve Yegge는 한때 Scala를 공격 했습니다. 누군가 나는 가이 API로 FUD퍼뜨리는 필드 데이를 가질 것이라고 걱정합니다 (조쉬 블로흐가 JCP 가 자바에 클로저를 추가 하는 것을 두려워한 것과 비슷합니다 ).

- 나는 믿고 다른, 분명해야 할 여호수아 블로흐 , 내가 제안이 실수를 표현하는 그의 정직-신념 이외의 BGGA 클로저 제안의 거부에 영향을 미칩니다.


제 아내와 동료들이 계속 말하고있는 것이 무엇이든, 제가 제가 바보라고 생각하지 않습니다. 저는 옥스포드 대학 에서 수학을 전공 거의 12 년 동안 상업적으로 프로그래밍을 해왔고 스칼라 에서 약 1 년 (상업적으로도).

선동적인 제목은 1980 년대 초 영국 선언문에 대한 인용문 이라는 점에 유의하십시오 . 이 질문은 주관적이지만 진짜 질문입니다. CW로 만드는 것이 문제에 대한 의견을 듣고 싶습니다.


"자살 유서"가 아니길 바라지 만 당신의 요점은 알 수 있습니다. 당신은 Scala의 강점과 문제인 확장 성에 부딪 쳤습니다 . 이를 통해 대부분의 주요 기능을 구현할 수 있습니다. 일부 다른 언어에서는 시퀀스 가 내장 map되거나 collect내장되어 있고 컴파일러가 원활하게 작동하도록하기 위해 모든 후프를 볼 필요가 없습니다. Scala에서는 모든 것이 라이브러리에 공개되어 있습니다.

사실 map그것의 복잡한 유형에 의해 지원되는 기능 은 꽤 발전했습니다. 이걸 고려하세요 :

scala> import collection.immutable.BitSet
import collection.immutable.BitSet

scala> val bits = BitSet(1, 2, 3)
bits: scala.collection.immutable.BitSet = BitSet(1, 2, 3)

scala> val shifted = bits map { _ + 1 }
shifted: scala.collection.immutable.BitSet = BitSet(2, 3, 4)

scala> val displayed = bits map { _.toString + "!" }
displayed: scala.collection.immutable.Set[java.lang.String] = Set(1!, 2!, 3!)

항상 최상의 유형을 얻는 방법을 보십니까? Ints를 Ints에 매핑 하면 다시 a를 얻지 BitSetInts를 Strings에 매핑 하면 Set. 지도 결과의 정적 유형과 실행 표현은 모두 전달 된 함수의 결과 유형에 따라 전달됩니다. 그리고 작동 기능이 적용되지 않습니다! 내가 아는 한 동등한 기능을 가진 다른 컬렉션 프레임 워크는 없습니다. user-의 관점 그러나 에서이 일을하는 방법입니다 가정 일에.

우리가 가진 문제는 모든 영리한 기술이 무서워하는 유형 시그니처로 유출 것입니다. 그러나 기본적으로 사용자에게 map? 의 전체 서명 유형이 표시되지 않습니다 . 어떻게 그녀가 고개를 경우에 대해 그녀 가지고 있는지 mapBitSet대해 :

map(f: Int => Int): BitSet     (click here for more general type)

이 경우 문서는 사용자 관점에서 실제로지도 유형이 있기 때문에 거짓말하지 않습니다 (Int => Int) => BitSet. 그러나 map다른 링크를 클릭하여 검사 할 수있는 일반적인 유형도 있습니다.

우리는 도구에서 이와 같은 기능을 아직 구현하지 않습니다. 하지만 사람들을 겁주지 않고 더 유용한 정보를 제공하기 위해 이렇게해야한다고 생각합니다. 이와 같은 도구를 사용하면 스마트 프레임 워크와 라이브러리가 자살하지 않을 것입니다.


저는 박사 학위도없고, CS 나 수학, 다른 분야의 학위도 가지고 있습니다. 저는 Scala 나 다른 언어에 대한 사전 경험이 없습니다. 원격으로없는 수있는 유형 시스템도 경험이 없습니다. 사실, 유형 시스템을 가지고 있는 피상적 인 지식 이상을 가진 유일한 언어 는 파스칼이며 정교한 유형 시스템으로 정확히 알려지지 가능성이 있습니다. (있지만가 않습니다 AFAIK 꽤 많이 다른 언어가 범위 유형을 가지고 있지만 , 여기서는 정말 관련이 없습니다.) 내가 아는 다른 3 개 국어 심지어 타입 시스템이 어느 것도 BASIC, 스몰 토크와 루비입니다.

하지만 map게시 함수 의 서명을 이해하는 데 전혀 문제가 없습니다 . 내가 map본 다른 모든 언어에 있는 것과 거의 동일한 서명처럼 보입니다. 차이점은이 버전이 더 일반적이라는 것입니다. Haskell보다 C ++ STL과 비슷한 해합니다. 특히, 인수가임을 요구하여 구체적인 컬렉션 유형 IterableLike에서 추상화하고, 결과 값 컬렉션에서 계획을 구축 할 수있는 암시 적 변환 함수가 존재하도록 요구하는 구체적인 반환 유형에서 추상화 합니다. 예, 복잡하지만 실제로는 일반적인 프로그래밍의 패러다임의 표현 일뿐입니다. 실제로 필요하지 않은 것을 가정하지 않습니다.

경우이 map실제로 컬렉션이 목록이거나 정렬되거나 정렬 가능하거나 이와 유사한 것이 필요 하지 않습니다 . 유일하게 map신경 쓰는 것은 컬렉션의 모든 요소에 순차적으로 액세스 할 수 있습니다. 그리고 결과 컬렉션이 무엇인지 알 필요가 빌드 방법 만 알면됩니다. 그래서 그것이 타입 서명이 요구하는 것입니다.

그래서 대신

map :: (a → b) → [a] → [b]

, 대한 전통적인 유형에 시그니처이며 map구체적이 List아니라 IterableLike데이터 구조 요구하도록 일반화되었습니다.

map :: (IterableLike i, IterableLike j) ⇒ (a → b) → i → j

그런 다음 결과를 사용자가 원하는 데이터 구조 로 변환 할 수있는 함수가 존재 합니다.

map :: IterableLike i ⇒ (a → b) → i → ([b] → c) → c

구문이 조금 더 복잡하다는 것을 인정하지만 의미는 동일합니다. 기본적으로

def map[B](f: (A) ⇒ B): List[B]

의 서명입니다 map. (스칼라의 객체 지향 특성으로 인해 입력 목록 매개 변수가 사라졌습니다 . 이제 단일 디스패치 OO 시스템의 모든 메소드가 갖는 암시 적 수신자 매개 변수가 되었기 때문입니다 .) 다음 구체적 그런 List에서보다 일반적인 것으로 일반화되었습니다.IterableLike

def map[B](f: (A) ⇒ B): IterableLike[B]

이제 IterableLike결과 컬렉션을 거의 모든 것을 생성 하는 함수로 대체합니다 .

def map[B, That](f: A ⇒ B)(implicit bf: CanBuildFrom[Repr, B, That]): That

어떤 정말 생각없는 것을 열심히 이해합니다. 실제로 필요한 지적 도구는 몇 가지뿐입니다.

  1. 무엇인지 (대략) 알아야 map합니다. 메소드 이름없이 타입 시그니처 주면 무슨 일이 일어나고 있는지 알아 내기가 훨씬 더 어려운 것입니다. 하지만 당신은 이미부터 알고 무엇map신속하게, 이상 현상의 서명과 서명을 검색 할 수 있고, 어떻게해야할지, 당신은 그 유형의 무엇인지 "왜 map인수로 두 가지 기능이 아니라 하나 의 테이크를? "
  2. 실제로 서명을 읽을 수 있어야합니다 . 그러나 이전에 Scala를 본 적이없는 것이 매우 쉬울 것입니다. 다른 언어에서 이미 알고있는 유형 구문의 혼합 일뿐입니다. VB.NET은 대표 변수 다형성에 대괄호를 사용하고 화살표를 사용하여 반환 유형과 구분하는 것이 실제로 표준입니다.
  3. 일반적인 프로그래밍이 무엇인지 알아야합니다. ( 기본적으로 모두 이름에 나와 있기 때문에 알아 내기가 그렇게 어렵지 않습니다 . 말 그대로 일반적인 방식으로 프로그래밍하는 것 입니다 .)

이 세 가지 중 어느 것도 전문 프로그래머 또는 취미 프로그래머에게 심각한 골칫거리를주지합니다. map지난 50 년 동안 디자인 된 거의 모든 언어의 표준 기능 기능. HTML과 CSS로 웹 사이트를 디자인 한 사람이라면 누구나 다른 언어가 다른 구문을 가지고있는 사실을 알 수 있고 심지어 원격 프로그래밍도 구독 할 수 없습니다. 일반 프로그래밍의 장점을 설명하는 St. Stepanov 교회의 성가신 C ++ 팬이없는 관련 메일 링리스트.

예, Scala 복잡합니다. 예, Scala는 인간에게 가장 정교한 유형 시스템 중 하나를 보유하고 있고 Haskell, Miranda, Clean 또는 Cyclone과 같은 언어와 경쟁하고 심지어 능가합니다. 그러나 아직 전에이 프로그래밍 언어의 성공에 대한 논쟁이라면 C ++는 오래 전에 계획을 작성하고있을 것입니다. Scala가 성공하지 못했던 이유는 많이 말할 프로그래머가 키보드 앞에 앉기 전에 두뇌를 켜는 것이 찮게 할 수 있다는 사실이 주된 이유가 아닐 것입니다.


C ++ 그렇습니다.

template <template <class, class> class C,
          class T,
          class A,
          class T_return,
          class T_arg
              >
C<T_return, typename A::rebind<T_return>::other>
map(C<T, A> &c,T_return(*func)(T_arg) )
{
    C<T_return, typename A::rebind<T_return>::other> res;
    for ( C<T,A>::iterator it=c.begin() ; it != c.end(); it++ ){
        res.push_back(func(*it));
    }
    return res;
}

글쎄, 일반 나는 당신의 고통을 당신과 나 같은 사람들 또는 거의 모든 것이 아닙니다. Stack Overflow 사용자는 규칙입니다.

내 말은 ... 대부분의 프로그래머는 타입 시그니처에 신경 쓰지 않을 것입니다 . 왜냐하면 절대 볼 수 없기 때문입니다 ! 그들은 문서를 읽지 않습니다.

가 어떻게 작동 코드하는지에, 대한 몇 가지 예를보고 코드가 예상 한 결과를 생성하는 데 실패하지 않는 한 문서를 보지 않을을 구석으로입니다. 실패하면 설명서를보고 맨 위에 사용 예제 를 볼 수 있습니다 .

그 점을 염두에두고 다음과 같이 생각합니다.

  1. 그 타입 시그니처를 접한 사람은 누구나 (대부분의 사람들과 많은) 스칼라에 대해 사전에 성향이 있으면 끝까지 조롱하고 스칼라를 좋아한다면 스칼라의 힘의 상징으로 할 것입니다.

  2. 문서가 사용 예제를 제공하고 메소드의 용도와 사용 방법을 명확하게 설명하도록 권장하지 않는 경우 Scala 채택을 약간 덜 뜨릴 수 있습니다.

  3. 장기적으로는 중요하지 않습니다. 스칼라 스칼라 용으로 작성된 라이브러리를 훨씬 더 강력하고 안전하게 사용할 있는 것과 같은 작업을 수행 할 수 있습니다. 이러한 라이브러리와 프레임 워크는 강력한 도구에 매료 된 프로그래머를 끌어들일 것입니다.

  4. 단순성과 직접성을 좋아하는 프로그래머는 계속해서 PHP 또는 사용할 언어를 사용할 것입니다.

아아, 프로그래머는 파워 툴에 많은 관심을 갖고 있기 때문에 이에 대한 대답으로 저는 주류 스칼라 채택에 대한 기대치를 수정했습니다. 저는 스칼라가 주류 언어가 될 전혀 의심의 여지가 없습니다. C 주류가 아니라 Perl 주류 또는 PHP 주류 일 수 있습니다.

Java에 대해보다, 클래스 로더를 교체 한 적이 있습니까? 관련 내용을 본 적이있는 적이 있습니까? 프레임 워크 작성자가하는 작업을 보면 Java는 무섭습니다. 대부분의 사람들은 Scala, IMHO에도 똑같은 것이 적용되어 얼리 어답터는 마주 치는 아래에 숨어 있는지 확인하는 경향이 있습니다.


이로 인해 사람들이 스칼라로 오는 것을 방해할까요?

예, 그것은 또한 사람들이 연기되는 것을 막을 것입니다. 나는 Scala가 더 높은 유형의 유형에 대한 지원을 얻은 이후로 더 높은 유형의 유형을 사용하는 컬렉션의 부족을 주요 약점으로했습니다. API 문서를 더 복잡하게 만들지 만 실제로 더 자연스럽게 만듭니다.

이것이 상업 세계에서 스칼라를 헌신적 인 박사 과정에서만이 만들까요 학문적 장난감으로 불리하게? CTO와 소프트웨어가 무서워할까요?

아마 그럴 것입니다. 저는 Scala가 많은 "전문적인"개발자들에게 접근 할 수 있다고 생각합니다. 부분적으로는 Scala의 부분적으로는 많은 개발자들이 배우기를 꺼려하기 때문입니다. 발표 개발자를 고용하는 CTO는 당연히 두려워 할 것입니다.

도서관 재 설계가 현명한 아이디어였습니까?

물론입니다. 여전히 약간의 가장자리가 있긴하지만 나머지 언어 및 유형 시스템과 훨씬 더 잘 맞습니다.

scala를 상업적으로 사용하고 권한에 대해 걱정하십니까? 2.8을 즉시 채택 할 계획입니까, 아니면 어떤 일이 발생하는지 기다릴 계획입니까?

나는 그것을 상업적으로 사용하지 않습니다. 2.8.x 시리즈를 도입하기 전에 최소한 몇 번의 revs가 때까지 기다릴 것입니다. 또한 EPFL이 릴리스 프로세스를 개선하는 데 얼마나 많은 성공을 거두 었는지 기다릴 것입니다. 내가보고있는 것은 희망적으로 보이지만 보수적 인 회사에서 일합니다.

"스칼라가 주류 개발자들에게 너무 복잡하고?"라는 좀 더 일반적인 주제 중 하나 ...

주류 또는 기타의 개발자는 기존 시스템을 유지하거나 확장하고 있습니다. 이것은 그들이 사용하는 대부분의 것입니다. 여전히 많은 사람들이 COBOL을 작성하고 있습니다.

내일의 주류 개발자는 현재 구축되고 애플리케이션을 유지하고 확장 할 것입니다. 대부분은 주류 개발자가 빌드하지 않습니다. 미래의 주류 개발자는 가장 성공적인 새로운 애플리케이션 개발자가 사용하는 언어를 사용할 것입니다.


Scala 커뮤니티가 Scala를 처음 접하는 프로그래머의 두려움을 덜어 줄 수있는 한 가지 방법은 연습에 집중하고 예를 들어는 것입니다. 이 접근 방식을 사용하는 몇 가지 사이트는 다음과 가변합니다.

Scala와 그 라이브러리는 설계 및 구현이 사용하기 어렵지 않다는 것입니다.


저는 저렴한 "대량 시장"미국 대학에서 학사 학위를 받기 때문에 인텔리전스 (또는 교육 수준) 규모의 중간에 빠졌다고 말하고 싶습니다. :) 저는 몇 달 동안 Scala와 손을 대고 동안. 사소하지 않은 2 ~ 3 개의 앱에서 작업했습니다.

특히 IntelliJ가 IMHO가 현재 최고의 Scala 플러그인 인 훌륭한 IDE를 제작했기 때문에 Scala 개발은 어렵지입니다.

  • 저는 Scala를 "세미콜론이없는 자바"로 사용할 수 있습니다. 즉, Java에서 작성한 것과 같은 모양의 코드를 작성하고 유형 추론으로 얻은 것과 같은 구문 적 간결함을 통해 약간의 이점을 얻을 수 있습니다. 예외 처리는 내가 할 때 더 편리합니다. getter / setter 상용구 없이는 클래스 정의가 훨씬 덜 장황합니다.

  • 가끔은 여러 줄의 Java와 동일한을 수행하기 위해 한 줄을 작성합니다. 해당되는 경우지도, 접기, 수집, 필터링 같은 기능적 방법의 체인은 구성하는 것이 재미 있고 또한 우아합니다.

  • Scala의 더 강력한 기능인 클로저와 (또는 커리) 함수, 패턴 매칭 등의 혜택을 거의 없습니다.

계속해서 저는 간결하고 관용적 인 구문으로 계속 어려움을 겪습니다. 매개 변수가없는 메소드 호출은 그들이하는 곳을 제외하고는 괄호가 필요하지 않습니다. 매치 문의 사례에는 굵은 화살표 ( =>)가 필요하지만 화살표 ( ->) 가 필요한 위치도 있습니다 . 많은 메소드는 짧지 만 다소 애매한 이름을 가지고 있습니다. /:또는 \:-충분한 매뉴얼 페이지를 넘기면 내 작업을 완료 할 수 있습니다 내 코드 중 일부는 Perl 또는 노이즈처럼 보이게합니다. 아이러니하게도, 가장 인기있는 구문 속기 중 하나가 Int작동하지 않습니다 . 저는 ++메소드를 정의하지 않습니다 .

이것은 내 의견 일뿐입니다. 저는 Scala가 C ++의 견제와 가독성과 결합 된 C ++의 힘을 가지고 있다고 생각합니다. 언어의 구문 상으로 인해 API 문서를 읽기도 어렵습니다.

Scala는 여러면에서 매우 잘 생각 되고 훌륭합니다. 많은 학자들이 프로그램을 좋아할 생각합니다. 그러나 그것은 또한 잡동사니로 가득 차있고 Java보다 훨씬 더 높은 학습을 가지고 읽기가 더 어렵습니다. 포럼을 훑어보고 얼마나 많은 개발자들이 여전히 자바의 미세한 부분으로 어려움을 겪고 어디에 있는지 스칼라가 주류 언어가 될 생각할 수 없습니다 . 이전에는 1 주 Java 코스 만 필요했던 3 주 Scala 코스에 개발자를 구비하고 있습니다.


나는 그 방법의 주된 문제는 (implicit bf : CanBuildFrom[Repr, B, That])설명도없이 진행 된다는 것입니다. 암시 적 인수가 무엇인지 확인하지 않습니다. scaladoc을 쫓는 것은 나를 더 혼란스럽게 할뿐입니다 ( CanBuildFrom문서가있는 것과 관련된 클래스는 거의 없습니다 ).

나는 단순한 " 반환 유형에, 대한 bf유형의 object-에, 대한 빌더를 제공하는 범위에 암시 적 object-가 있어야한다 "는 것이 다소 도움이 될 것이라고 생각 하지만 ,이 정말로하고 당신 싶은 모든 것이 '에스. 사실, 나는 그 유형이 무엇을 의미 하는지 모르기 때문에 그것이 옳은지 확신하지 못합니다 . 그리고 문서는 확실히 전혀 단서를주지 않습니다.BThatABReprTraversable

따라서 두 가지 옵션이 남았습니다. 둘 다 즐겁지 언어.

  • 이전지도가 작동하는 방식과 대부분의 다른 언어에서지도가 작동하는 방식 만 작동 가정합니다.
  • 소스 코드를 좀 더 파헤쳐 라

나는 Scala가 고유 한 것들이 어떻게 작동하는지에 대한 배짱을 드러내고 그리고 그것이 바로 oxbow_lakes가 설명하는 것을 수행하는 방법을 제공한다는 것을 압니다. 그러나 그것은 서명의 산만 함입니다.


저는 Scala 확실하고 솔직히 유형 서명에 문제가 있다고 생각합니다. 매개 변수는 매핑 할 함수이고 빌더가 올바른 콜렉션을 리턴하는 암시 적 변수입니다. 명확하고 읽기만합니다.

사실 모든 것이 아주 우아합니다. 빌더 유형 매개 변수를 사용하면 컴파일러가 리턴 올바른 유형을 선택하고 암시하는 추가 변수를 사용하는 클래스. 나는 시도 시도했다 :

Map(1 -> "a", 2 -> "b").map((t) => (t._2) -> (t._1)) // returns Map("a" -> 1, "b" -> 2)
Map(1 -> "a", 2 -> "b").map((t) =>  t._2)            // returns List("a", "b")

바로 다형성입니다.

당연히 주류 패러다임이 많은 사람들을 놀라게 할 것입니다. 그러나 표현력과 우아함을 중시하는 많은 사람들을 끌어들일 것입니다.


안타깝게도 귀하가 제공하는 한지도의 서명은지도에 대한 서명 잘못된 판이 있습니다.

첫 번째 비판은지도의 시그니처를 전복에서 더 많이 사용하는 것입니다. 이것은 기본적으로 미덕이라고 믿는 것은 일반적인 오류입니다. 발음합니다. 맵 함수는 구성과 동일성의 두 가지 법칙을 준수하는 공변 펑터 Fx-> (x-> y)-> Fy로 매우 잘 정의됩니다. "지도"에 기인하는 모든 것은 희화입니다.

주어진 서명은 다른 것이지만지도가 아닙니다. 내가 생각하는 반복자 패턴의 본질이라는 논문의 "traverse"시그니처의 전문화되고 약간 변경된 버전입니다. 그 서명은 다음과 같다.

traverse :: (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b)

스칼라로 변환하겠습니다.

def traverse[A, B](f: A => F[B], a: T[A])(implicit t: Traversable[T], ap: Applicative[F]): F[T[B]

물론 실패합니다-충분히 일반적이지 않습니다! 또한 약간의 추가 (Identity functor를 통해 트래버스를 실행하여 맵을 얻을 수 있습니다). 그러나 라이브러리 작성자가 잘 문서화 된 라이브러리 일반화에 대해 더 잘 알고 있다는 것 (효과적인 것보다 우선)이 오류가 표시되지 않을 것입니다.

둘째,지도 함수는 이해를위한 용도로 사용되기 때문에 스칼라에서 특별한 경우입니다. 이것은 불행히도 더 잘 갖추어 진 도서관 설계자는 이해의 통사론 적을 무시하지 않고서는 무시할 수 있다는 것을 의미합니다. 즉, Scala 라이브러리 디자이너가 방법을 파괴한다면 이것이 발견 매핑하지!

나는 누군가가 진술하기를 바랍니다. 왜냐하면 그것은 스칼라가 주장하는 오류를 해결하기가 더 어려워 질 것이 때문입니다. 분명히 제가 반대하는 이유입니다. 즉, "일반적인 프로그래머의 무책임한 (즉, 너무 힘들다!)"에 대한 해결책은 "더 쉽게 만들도록 달래주는 것"이 ​​아니라 더 나은 프로그래머가되기위한 지침과 지원을 제공하는 것입니다. 나 자신과 스칼라의 목표는이 문제에 대해 논의 중이지만, 당신의 요점으로 돌아갑니다.

당신은 아마도 "일반적인 프로그래머"로부터 구체적인 반응을 예측하면서 당신의 주장을했을 것입니다. 즉, "하지만 너무 복잡하다!"라고 주장 할 사람들입니다. 또는 일부. 당신이 참조하는 Yegges 또는 Blochs입니다. 반지성주의 / 실용주의 운동에 대한이 사람들에 대한 나의 반응은 상당히 가혹하고 이미 많은 반응을 예상하고 있으므로 생략하겠습니다.

Scala 라이브러리가 개선하고 오류가 안심하고 구석에 숨겨지기를 바랍니다. 자바는 "유용한 일을 시도하는 것"이 ​​엄청나게 비용이 많이 들고, 엄청난 양의 오류를 피할 수 없기 때문에 가치가없는 언어입니다. 나는 스칼라에게 같은 길로 가지 말라고 간청한다.


나는 질문과 Martin의 대답에 전적으로 동의합니다. :). Java는 제네릭을 사용하여 javadoc을 읽는 것은 추가 노이즈로 인한 것보다 훨씬 어렵습니다. 이 질문의 예제 코드에서와 같이 암시 적 매개 변수가 사용되는 Scala에서 합성됩니다 (암시 물은 매우 유용한 컬렉션 모핑 작업을 수행함).

나는 그것이 언어 자체의 문제라고 생각하지 않는 것이 더 많은 도구 문제라고 생각합니다. 그리고 Jörg W Mittag의 말에 동의하지만 scaladoc (또는 IDE의 유형 문서)을 통해 보면 방법이 무엇인지, 무엇을 취하고 반환하는지에 대한 가능한 두뇌 능력이 필요하다고 생각합니다. 그것을 위해 약간의 종이에 약간의 대수학을 해킹 할 필요가 없어야합니다. :)

확실히 IDE는 모든 변수 / 예제 / 유형에 대한 모든 메소드를 표시하는 좋은 방법이 필요합니다 (Martin의에서와 모든 제네릭을 인라인 할 수 있으므로 멋지고 쉽게 수 있음). 나는 기본적으로 암시적인 것을 숨기는 것을 Martin의 아이디어도 좋아합니다.

scaladoc에서 예제를 사용하는 경우 ...

def map[B, That](f: A => B)(implicit bf: CanBuildFrom[Repr, B, That]): That

scaladoc에서 볼 때 기본적으로 [B, That] 일반 블록과 암시 적있는 변수 (마우스로 작은 아이콘을 가리키면 표시)가 숨겨 지길 원합니다. 일반적으로 관련이없는 읽기. 예를 들어 이렇게 생겼는지 상상했을 때 ...

def map(f: A => B): That

그것이 무엇인지 명확하고 분명합니다. 예를 들어 'That'이 무엇인지 궁금 할 수 있습니다. 예를 들어 마우스를 올리거나 클릭하면 'That'을 강조 표시하는 [B, That] 텍스트가 확장 될 수 있습니다.

[] 선언 및 (암시 적 ...) 블록에 작은 아이콘을 사용할 수 있으므로 문장의 일부가 축소되어 있음을 알 수 있습니까? 토큰을 사용하기는 어렵지만. 지금은 ...

def map.(f: A => B).: That

따라서 기본적으로 기본적으로 시스템의 '노이즈'는 사람들이 생겼을 때 주요 80 % (메소드 이름 확장, 다음 변수 유형 및 반환 유형을 간단하고 간결한 방식으로 표시) 숨겨져 있고 세부 사항에 대한 가능한 링크가 거의 없습니다. 정말 그렇게 신경 쓰면 요

대부분의 사람들은 유형에서 할 수있는 메소드와 호출 수있는 호출 변수를 찾기 위해 scaladoc을 있습니다. 우리는 많은 세부 사항을 사용자에게 제공합니다.

여기 또 다른 예가 있습니다 ...

def orElse[A1 <: A, B1 >: B](that: PartialFunction[A1, B1]): PartialFunction[A1, B1]

이제 제네릭 선언을 숨기면 읽기가 더 있습니다.

def orElse(that: PartialFunction[A1, B1]): PartialFunction[A1, B1]

그런 다음 사람들이 A1 위로 마우스를 가져 가면 A1이 A1 인 선언을 보여줄 수 있습니다. <: A. 제네릭의 공변 및 반 변형 유형도 많은 노이즈를 추가하여 사용자에게 쉽게 접근 할 수있는 방식으로 할 수 있습니다.


나는 그것을 깨는 방법을 모르지만 캠브리지에서 박사 학위를 2.8을 잘 사용하고 있습니다.

더 진지하게, 나는 2.7 (내가 사용하고있는 자바 라이브러리와 상호 운용하지 않을 것임)을 거의 사용하지 않을 것입니다. 한 달 전에 Scala를 사용하기 시작했습니다. 나는 Haskell에 대한 경험이 사용합니다 (별로는 상관) 걱정하는 것을 무시하고 Java에 대한 경험과 일치하는 방법을 찾았습니다 (생계를 위해).

그래서 : 저는 "새로운 사용자"이고 미루지입니다. Java처럼 확실하다는 사실은 제가 이해하지 못한 확신을 복제 할 수 있습니다.

(하지만 내가 Scala를 봤던 이유는 부분적으로 그것을 작업에 밀어 넣을지 여부를보기 위해 였고, 아직 그렇게하지 않을 것입니다. 확실히 도움이 될 것입니다. 변화하고 개발되고 있습니다. 말해서 가장 놀랐던 것은 그것이 얼마나 굉장한가 였지만 변화는 거의 두 번째에 이르렀습니다).


Scala를 전혀 모르지만 몇 주 전에 Clojure를 읽을 수 없었습니다. 이제는 대부분을 읽을 수 있지만 가장 단순한 예를 넘어서는 어떤 것도 쓸 수 없습니다 . 스칼라도 다르지 않다고 생각합니다. 배우는 방법에 따라 좋은 책이나 코스가 필요합니다. 그냥 읽기 지도의 위의 선언을, 내가 가지고 어쩌면 그것의 1/3.

더 큰 문제는 이러한 언어의 구문이 아니라 일상적인 프로덕션 코드에서 사용할 수 있는 패러다임채택하고 내재화하는 것이라고 생각합니다 . 나를 위해 자바 등 파스칼의 모든에서 도약하지 않았다 C,도 기본에서 큰 도약이 아니었다 C ++에서 큰 도약이 아니었다 ...하지만 Clojure에서 같은 기능의 언어로 코딩 이다 (대한 거대한 도약 어쨌든 나). Scala에서는 Java 스타일이나 Scala 스타일로 코딩 할 수 있다고 생각합니다. 그러나 Clojure에서는 Java에서 명령 적 습관을 유지하려는 노력이 상당히 엉망이 될 것입니다.


Scala에는 매우 복잡하고 학술적으로 보이지만 사용하기 쉽게 디자인 된 많은 미친 기능 (특히 암시 적 매개 변수와 관련된 경우)이 있습니다. 가장 유용한 것들은 구문 적 설탕 ( [A <% B]유형 A의 객체가 B 유형의 객체로의 암시 적 변환이 있음을 의미)과 그들이하는 일에 대한 잘 문서화 된 설명을 얻습니다 . 그러나 대부분의 경우 이러한 라이브러리의 클라이언트로서 암시 적 매개 변수를 무시하고 올바른 작업을 수행하도록 신뢰할 수 있습니다.


이로 인해 사람들이 스칼라로 오는 것을 막을 수 있습니까?

Scala는 많은 힘을 가지고 있고 그 구문은 Haskell, OCaml, SML, Lisps와 같이 Java / C ++ / PHP 프로그래머에게 이질적이지 않기 때문에 그것이 Scala의 인기에 영향을 미치는 주요 요인이라고 생각하지 않습니다. 기타..

하지만 저는 스칼라의 인기가 현재 자바보다 덜 정체 될 것이라고 생각합니다. 왜냐하면 저는 다음 주류 언어가 훨씬 단순화되어야한다고 생각하기 때문입니다. 그리고 거기에 도달하기위한 유일한 방법은 순수한 불변성, 즉 HTML과 같은 선언적이지만 튜링은 완전합니다. . 그러나 나는 그런 언어를 개발하고 있기 때문에 편견이 있지만 몇 달에 걸친 연구를 통해 Scala가 내가 필요로하는 것을 충분하지 않다는 것을 배제한 후에야 그렇게했습니다.

이것이 상업 세계에서 스칼라를 헌신적 인 박사 과정 학생들 만 이해할 수있는 학문적 장난감으로 나쁜 이름으로 만들까요? CTO와 소프트웨어 책임자가 무서워할까요?

나는 Scala의 명성이 Haskell 콤플렉스로 인해 타격을받을 것이라고 생각하지 않습니다. 하지만 대부분의 프로그래머가 스칼라를 사용하도록 강요하는 유스 케이스를 아직 보지 못하고 학습을 미루게 될 것이기 때문에 일부는 학습을 미룰 것이라고 생각합니다. 아마도 확장 성이 높은 서버 측이 가장 매력적인 사용 사례 일 것입니다.

그리고 주류 시장에서 스칼라를 처음 배우는 것은 처음으로 HTML이나 Python을 사용하는 것과 같이 프로그램을 즉시 작성하는 "신선한 공기의 숨결"이 아닙니다. 스칼라는 처음부터 우연히 발견되는 모든 세부 사항을 배운 후에 성장하는 경향이 있습니다. 그러나 처음부터 Programming in Scala를 읽었다면 학습 곡선에 대한 내 경험과 의견이 달랐을 것입니다.

도서관 재 설계가 현명한 아이디어였습니까?

명확히.

Scala를 상업적으로 사용하고 있다면 이것에 대해 걱정하십니까? 2.8을 즉시 채택 할 계획입니까? 아니면 어떤 일이 발생하는지 기다리십니까?

새 언어의 초기 플랫폼으로 Scala를 사용하고 있습니다. Scala를 상업적으로 사용한다면 Scala의 컬렉션 라이브러리에서 코드를 작성하지 않을 것입니다. 한 번 살펴 보았을 때 Scalaz의 형식 서명이 Scala의 컬렉션 라이브러리보다 훨씬 더 장황하고 다루기 힘들다는 사실을 발견했기 때문에 나만의 범주 이론 기반 라이브러리를 만들었습니다. 그 문제의 일부는 아마도 스칼라의 타입 클래스 구현 방식 일 것입니다. 이것이 제가 제 언어를 만드는 사소한 이유입니다.


저는이 답변을 작성하기로 결정했습니다. 스칼라의 컬렉션 클래스 디자인을 제가 제 언어로하고있는 것과 비교하고 연구하고 싶었 기 때문입니다. 내 생각 과정을 공유 할 수도 있습니다.

빌더 추상화의 2.8 Scala 컬렉션 사용은 건전한 디자인 원칙입니다. 아래에서 두 가지 디자인 장단점을 살펴 보겠습니다.

  1. WRITE-ONLY CODE :이 섹션을 작성한 후 Carl Smotricz의 의견읽었 습니다.이 의견 은 제가 예상하는 트레이드 오프에 동의합니다. James Strachan과 davetron5000의 의견은 That의 의미 (That [B]도 아님)와 암시 적 메커니즘이 직관적으로 이해하기 쉽지 않다는 점에 동의합니다. 아래의 문제 # 2에서 모노 이드 사용을 참조하십시오. Derek Mahar의 의견은 Scala 작성에 관한 것이지만 "일반적인 경우"가 아닌 다른 사람의 Scala를 읽는 것은 어떻습니까?

    내가 스칼라에 대해 읽은 비판 중 하나는 다른 사람들이 작성한 코드를 읽는 것보다 작성하는 것이 더 쉽다는 것입니다. 그리고 여러 가지 이유 (예 : 함수를 작성하는 여러 방법, 자동 폐쇄, DSL 용 단위 등)로 인해이 경우가 사실 인 경우가 있지만 이것이 주요 요인인지 여부는 결정되지 않았습니다. 여기서 암시 적 함수 매개 변수의 사용에는 플러스와 마이너스가 있습니다. 플러스 측면에서는 상세 정보를 줄이고 빌더 개체 선택을 자동화합니다. Odersky의 예에서BitSet, 즉 Set [Int]에서 Set [String]으로의 변환은 암시 적입니다. 익숙하지 않은 코드 독자는 현재 패키지 범위에 존재할 수있는 모든 잠재적 인 보이지 않는 암시 적 빌더 후보에 대해 잘 추론 할 수 없다면 컬렉션 유형이 무엇인지 쉽게 알지 못할 수 있습니다. 물론 숙련 된 프로그래머와 코드 작성자는 BitSet이 Int로 제한되어 있으므로 String에 대한 맵을 다른 컬렉션 유형으로 변환해야한다는 것을 알 수 있습니다. 하지만 어떤 컬렉션 유형입니까? 명시 적으로 지정되지 않았습니다.

  2. AD-HOC COLLECTION DESIGN :이 섹션을 작성한 후 Tony Morris의 의견을 읽고 거의 같은 주장을 하고 있음을 깨달았습니다. 아마도 나의 더 장황한 설명이 그 요점을 더 분명하게 만들 것입니다.

    "Fighting Bit Rot with Types"Odersky & Moors에서는 두 가지 사용 사례가 제공됩니다. 이는 BitSet to Int 요소, Map to tuple 요소의 제한이며, 일반 요소 매핑 함수 A => B가 대체 대상 컬렉션 유형을 구축 할 수 있어야하는 이유로 제공됩니다. 그러나 이것은 범주 이론 관점에서 결함이 있습니다. 범주 이론에서 일관성을 유지하고 따라서 코너 케이스를 방지하기 위해 이러한 컬렉션 유형은 펑터입니다. 여기서 각 모피 즘 A => B는 동일한 펑터 범주, List [A] => List [B], BitSet에있는 객체간에 매핑되어야합니다. [A] => BitSet [B]. 예를 들어 Option은 하나의 Some (object) 및 None 집합의 모음으로 볼 수있는 펑터입니다. Option의 None 또는 List의 Nil에서 그렇지 않은 다른 펑터로의 일반 맵은 없습니다.

    여기에는 트레이드 오프 디자인 선택이 있습니다. 새 언어의 컬렉션 라이브러리 디자인에서 모든 것을 펑터로 만들기로 선택했습니다. 즉, BitSet을 구현하면 비 비트 필드 내부 표현을 사용하여 모든 요소 유형을 지원해야합니다. 정수 유형 매개 변수이며 해당 기능은 이미 스칼라에서 상속받은 세트에 있습니다. 그리고 내 디자인의 Map은 값만 매핑하면되며 (키, 값) 쌍 튜플을 매핑하기위한 별도의 비 펑터 메서드를 제공 할 수 있습니다. 한 가지 장점은 각 펑터가 일반적으로 응용 프로그램이며 아마도 모나드이기도하다는 것입니다. 따라서 요소 유형 사이의 모든 기능 (예 : A => B => C => D => ...)은 자동으로 해제 된 적용 유형 간의 함수로 해제됩니다. 예 : List [A] => List [B] => List [ C] => 목록 [D] => .... functor에서 다른 컬렉션 클래스로의 매핑을 위해, 저는 Nil, None, 0, "", Array () 등과 같은 monoid를 취하는 맵 오버로드를 제공합니다. 그래서 빌더 추상화 함수는 monoid의 append 메소드이고 필수 입력 매개 변수로 명시 적으로 제공되므로 보이지 않는 암시 적 변환이 없습니다. (Tangent :이 입력 매개 변수는 또한 Scala의 맵 디자인이 할 수없는 비어 있지 않은 모노 이드에 추가 할 수있게합니다.) 이러한 변환은 동일한 반복 패스에서 맵과 폴드입니다. 또한 카테고리 의미에서 "효과를 사용한 응용 프로그래밍"McBride & Patterson을 제공합니다.이 기능을 사용하면 순회 가능한 모든 응용 프로그램에서 대부분의 모든 컬렉션 클래스가 둘 다인 응용 프로그램으로의 단일 반복 패스에서 맵 + 접기가 가능합니다.

    따라서 Scala 컬렉션은 범주 이론에 근거하지 않는다는 점에서 "임시"이며 범주 이론은 상위 수준 표시 의미론의 본질입니다. Scala의 암시 적 빌더는 처음에는 펑터 모델 + 모노 이드 빌더 + 순회 가능-> 적용보다 "더 일반화"되어 있지만 어떤 카테고리와도 일치하지 않는 것으로 입증되지 않았기 때문에 어떤 규칙을 따르는 지 알 수 없습니다. 가장 일반적인 의미와 코너 케이스가 주어질 경우 카테고리 모델을 따르지 않을 수 있습니다. 더 많은 변수를 추가하면 더 일반적인 것을 만든다는 것은 사실이 아닙니다. 이것은 범주 이론의 큰 이점 중 하나였습니다. 이것은 더 높은 수준의 의미론으로 올라 가면서 일반성을 유지하는 규칙을 제공한다는 것입니다. 컬렉션은 범주입니다.

    나는 어딘가에서 읽었다. 라이브러리 디자인에 대한 또 다른 정당화로 Odersky라고 생각한다. 순수한 기능적 스타일의 프로그래밍은 꼬리 재귀가 사용되지 않는 제한된 재귀와 속도의 비용이 든다는 것이다. 나는 지금까지 내가 만난 모든 경우에 꼬리 재귀를 사용하는 것이 어렵다는 것을 발견하지 못했습니다.


또한 나는 Scala의 트레이드 오프 중 일부가 예를 들어 Haskell이나 내가 개발중인 언어와는 달리 변경 가능한 언어와 변경 불가능한 언어 모두가 되려고하기 때문이라는 불완전한 생각을 떠올리고 있습니다. 이것은 토니 모리스의 이해에 대한 의견과 일치합니다. 내 언어로는 루프와 변경 가능한 구조가 없습니다. 내 언어는 (현재로서는) Scala 위에 위치 할 것이며 그에 많은 빚을지게 될 것입니다. Scala에 일반적인 유형 시스템과 가변성이 없다면 이것은 불가능할 것입니다. 하지만 Odersky & Moors ( "Fighting Bit Rot with Types")는 Scala가 더 높은 종류를 가진 유일한 OOP 언어라고 말하는 것이 틀렸다고 생각하기 때문입니다. ML에는 그것들이 있습니다. 또한 SML의 유형 시스템은 (1980 년대 이후) 동등하게 유연 할 수 있습니다. 구문이 Scala만큼 Java (및 C ++ / PHP)와 많이 유사하지 않기 때문에 쉽게 인식되지 않을 수 있습니다. 어쨌든 이것은 스칼라에 대한 비판이 아니라 트레이드 오프에 대한 불완전한 분석을 제시하려는 시도이며, 이는 질문과 밀접한 관련이 있기를 바랍니다. Scala와 SML은 Haskell의 무능력으로 고통받지 않습니다.diamond multiple inheritance , 이것은 중요하며 Haskell Prelude의 많은 기능이 다른 유형에 대해 반복되는 이유를 이해합니다.


여기에 학위를 기재 할 필요가있는 것 같습니다 : 정치학 학사 및 컴퓨터 과학 학사.

요점 :

이로 인해 사람들이 스칼라로 오는 것을 막을 수 있습니까?

기본 프로그래밍 패러다임이 어렵 기 때문에 Scala는 어렵습니다. 함수형 프로그래밍은 많은 사람들을 두려워합니다. PHP로 클로저를 구축하는 것은 가능하지만 사람들은 거의하지 않습니다. 그래서 아니,이 서명이 아니라 나머지는 사람들이 근본적인 패러다임의 힘을 소중히 여기도록하는 특별한 교육이 없다면 사람들을 쫓아 낼 것입니다.

이 교육이 가능하다면 누구나 할 수 있습니다. 작년에 저는 SCALA에서 학교 아이들과 함께 체스 컴퓨터를 만들었습니다! 그들은 문제가 있었지만 결국에는 잘했습니다.

Scala를 상업적으로 사용하고 있다면 이것에 대해 걱정하십니까? 2.8을 즉시 채택 할 계획입니까? 아니면 어떤 일이 발생하는지 기다리십니까?

나는 걱정하지 않을 것입니다.


저도 옥스포드에서 수학 학위를 받았습니다! 새 컬렉션을 '얻는'데 시간이 좀 걸렸습니다. 하지만 지금은 많이 좋아합니다. 사실, '지도'의 타이핑은 2.7에서 저를 괴롭힌 첫 번째 큰 일 중 하나였습니다 (아마도 제가 한 첫 번째 작업은 컬렉션 클래스 중 하나의 서브 클래스 였을 것입니다).

새로운 2.8 컬렉션에 대한 Martin의 논문을 읽는 것은 암시 적 사용을 설명하는 데 실제로 도움이되었지만 문서 자체는 핵심 API의 메서드 서명 내에서 다른 종류의 암시 적 역할을 설명하는 더 나은 작업을 확실히 수행해야합니다.

저의 주요 관심사는 이것입니다. 2.8은 언제 출시 될까요? 버그 보고서가 언제 더 이상 수신되지 않습니까? 스칼라 팀이 2.8로 씹을 수있는 것보다 더 많이 물었거나 한 번에 너무 많이 바꾸려고 했습니까?

나는 새로운 것을 추가하기 전에 우선적으로 2.8이 릴리스를 위해 안정화되는 것을보고 싶고, 스칼라 컴파일러의 개발 로드맵이 관리되는 방식에 약간의 개선이있을 수 있는지 궁금합니다.


사용 사이트의 오류 메시지는 어떻습니까?

그리고 기존 유형을 DSL에 맞는 사용자 정의 유형과 통합해야하는 사용 사례는 어떨까요? 연관성, 우선 순위, 암묵적 변환, 암묵적 매개 변수, 상위 종류, 그리고 실존 적 유형에 대해 잘 교육 받아야합니다.

대부분 간단하지만 반드시 충분하지는 않다는 것을 아는 것은 매우 좋습니다. 광범위한 라이브러리를 설계하려면 최소한이 내용을 아는 사람이 한 명 있어야합니다.

참고 URL : https://stackoverflow.com/questions/1722726/is-the-scala-2-8-collections-library-a-case-of-the-longest-suicide-note-in-hist

반응형