복붙노트

[SCALA] 값이 할당보다는 단위로 평가 스칼라 할당에 대한 동기는 무엇입니까?

SCALA

값이 할당보다는 단위로 평가 스칼라 할당에 대한 동기는 무엇입니까?

값이 할당보다는 단위로 평가 스칼라 할당에 대한 동기는 무엇입니까?

I / O 프로그래밍의 일반적인 패턴은 다음과 같이 일을하는 것입니다 :

while ((bytesRead = in.read(buffer)) != -1) { ...

그러나이 때문에 스칼라 수 없습니다 ...

bytesRead = in.read(buffer)

... 단위, bytesRead 아닌 새로운 값을 반환합니다.

기능적인 언어에서 떠날 흥미로운 일처럼 보인다. 그것이 그렇게 한 이유 궁금?

해결법

  1. ==============================

    1.나는 할당이 아니라 단위보다 할당 된 값을 반환 가진 주창. 마틴과 나는 앞뒤로 계속했지만, 그의 주장은 스택에 값을 넣는 것은 단지 시간의 95 %를 그만 팝업 바이트 코드의 낭비이고 성능에 부정적인 영향을 미칠 것이 었습니다.

    나는 할당이 아니라 단위보다 할당 된 값을 반환 가진 주창. 마틴과 나는 앞뒤로 계속했지만, 그의 주장은 스택에 값을 넣는 것은 단지 시간의 95 %를 그만 팝업 바이트 코드의 낭비이고 성능에 부정적인 영향을 미칠 것이 었습니다.

  2. ==============================

    2.나는 실제 이유에 내부 정보에 관여하지 해요,하지만 내 의심은 매우 간단합니다. 스칼라 프로그래머가 자연에 대한-함축 선호 때문에 이렇게 사용 측면 effectful 루프 어색합니다.

    나는 실제 이유에 내부 정보에 관여하지 해요,하지만 내 의심은 매우 간단합니다. 스칼라 프로그래머가 자연에 대한-함축 선호 때문에 이렇게 사용 측면 effectful 루프 어색합니다.

    그것은 여러 가지 방법으로이 작업을 수행합니다. 예를 들어, 당신은 당신이 선언하고 변수를 변이 루프를 필요가 없습니다. 당신은 (쉽게) 당신은 당신이 자주 그냥 전에 돌연변이를 반복해야 의미합니다 조건을 테스트 동시에 while 루프에 상태 변이, 그리고 그것의 끝에 수 없습니다. 잠시 블록 내에서 선언 된 변수는 (...) 동안 수행하게하면서 시험 조건, {...}에서 볼 훨씬 덜 유용하지 않습니다. 등등.

    해결 방법 :

    while ({bytesRead = in.read(buffer); bytesRead != -1}) { ... 
    

    어떤 것이 가치가있다.

    다른 설명으로, 아마도 마틴 오더 스키는 이러한 사용에서 파생 몇 가지 매우 추한 버그에 직면했고, 자신의 언어에서 그것을 금지하기로 결정했다.

    편집하다

    데이비드 폴락은 명확 마틴 오더 스키 자신이 명태 내놓은 성능 관련 문제의 인수에 신뢰를주는 그의 대답을 주석 있다는 사실에 의해 승인 된 일부 실제 사실로 대답했다.

  3. ==============================

    3.이것은 더 "공식적으로 올바른"형 시스템을 가진 스칼라의 한 부분으로 일어났다. 공식적으로 말하는, 할당은 순전히 측면 초래 문이므로 단위를 반환해야합니다. 이 멋진 결과를 가지고; 예를 들어 :

    이것은 더 "공식적으로 올바른"형 시스템을 가진 스칼라의 한 부분으로 일어났다. 공식적으로 말하는, 할당은 순전히 측면 초래 문이므로 단위를 반환해야합니다. 이 멋진 결과를 가지고; 예를 들어 :

    class MyBean {
      private var internalState: String = _
    
      def state = internalState
    
      def state_=(state: String) = internalState = state
    }
    

    state_ = 메소드가 리턴 장치 (세터 예상되는 바와 같이) 정확하게 때문에 할당 반환 장치.

    나는 스트림 또는 이와 유사한 복사와 같은 C 스타일의 패턴이 특정 디자인 결정이 조금 골칫거리가 될 수 있음을 동의합니다. 그러나, 사실은 일반적으로 상대적으로 문제가없는 그리고 정말 타입 시스템의 전체적인 일관성에 기여한다.

  4. ==============================

    4.아마도 이것은 명령 쿼리 분리 원칙 때문이다?

    아마도 이것은 명령 쿼리 분리 원칙 때문이다?

    이 없거나 부작용 (객체를 변경 즉, 그)가없는 객체 메소드 사이에 분명한 차이를 만들어으로 CQS는 OO의 교회법 및 함수형 프로그래밍 스타일에서 인기있는 경향이있다. 변수 할당에 적용 CQS는 평소보다 더 복용하지만, 같은 생각이 적용됩니다.

    CQS가 유용한 이유의 짧은 그림 : 정렬 추가], 첫째, 및 길이 방법이있는 List 클래스와 가상 하이브리드 F / 각종 언어를 생각해 보자. 필수 OO 스타일에, 하나는이 같은 함수를 작성 할 수 있습니다 :

    func foo(x):
        var list = new List(4, -2, 3, 1)
        list.Append(x)
        list.Sort()
        # list now holds a sorted, five-element list
        var smallest = list.First()
        return smallest + list.Length()
    

    더 많은 기능 스타일 반면, 일 것 같은 가능성이 쓰기 뭔가 :

    func bar(x):
        var list = new List(4, -2, 3, 1)
        var smallest = list.Append(x).Sort().First()
        # list still holds an unsorted, four-element list
        return smallest + list.Length()
    

    이 같은 일을 시도하는 것 같다,하지만 분명 둘 중 하나가 잘못이며, 메소드의 동작에 대한 자세한 내용을 알지 못하고, 우리가 어떤 일을 말할 수 없다.

    CQS 사용하지만, 우리는 추가] 및 정렬 목록을 변경하는 경우, 그들은 때 우리가해서는 안 두 번째 양식을 사용하여, 따라서 버그를 만들기에서 우리를 방지 단위 유형을 반환해야한다고 주장한다. 부작용의 존재에 따라서도 메소드 서명에 내포된다.

  5. ==============================

    5.나는이 프로그램 / 부작용이없는 언어를 유지하기 위해 추측 것입니다.

    나는이 프로그램 / 부작용이없는 언어를 유지하기 위해 추측 것입니다.

    당신이 설명하는 것은 일반적인 경우에 나쁜 것은 고려 부작용의 의도적 인 사용이다.

  6. ==============================

    6.부울 표현으로 과제를 사용하는 가장 좋은 스타일이 아니다. 당신은 오류를 종종 초래 동시에 두 가지를 수행합니다. 그리고의 accidential 사용 "="대신 "=="의 Scalas 제한으로 피할 수있다.

    부울 표현으로 과제를 사용하는 가장 좋은 스타일이 아니다. 당신은 오류를 종종 초래 동시에 두 가지를 수행합니다. 그리고의 accidential 사용 "="대신 "=="의 Scalas 제한으로 피할 수있다.

  7. ==============================

    7.그런데 : 난 자바, 초기 동안 트릭 바보 찾을 수 있습니다. 왜이 같은 somethign하지?

    그런데 : 난 자바, 초기 동안 트릭 바보 찾을 수 있습니다. 왜이 같은 somethign하지?

    for(int bytesRead = in.read(buffer); bytesRead != -1; bytesRead = in.read(buffer)) {
       //do something 
    }
    

    부여, 할당은 두 번 표시하지만, 적어도 bytesRead는이 속한 범위에, 나는 재미 할당 트릭을 재생 아니에요 ...

  8. ==============================

    8.당신은 당신이 간접 대한 참조 유형이 이에 대한 해결 방법을 가질 수 있습니다. 순진한 구현에서는 임의의 유형에 대해 다음을 사용할 수 있습니다.

    당신은 당신이 간접 대한 참조 유형이 이에 대한 해결 방법을 가질 수 있습니다. 순진한 구현에서는 임의의 유형에 대해 다음을 사용할 수 있습니다.

    case class Ref[T](var value: T) {
      def := (newval: => T)(pred: T => Boolean): Boolean = {
        this.value = newval
        pred(this.value)
      }
    }
    

    그런 다음 나중에 참조에 액세스 할 수 ref.value 사용해야합니다 제약에 따라, 당신은 당신의 동안 술어를 쓸 수 있습니다

    val bytesRead = Ref(0) // maybe there is a way to get rid of this line
    
    while ((bytesRead := in.read(buffer)) (_ != -1)) { // ...
      println(bytesRead.value)
    }
    

    당신은 그것을 입력하지 않고도 더 암시 적 방식으로 bytesRead에 대한 검사를 할 수 있습니다.

  9. from https://stackoverflow.com/questions/1998724/what-is-the-motivation-for-scala-assignment-evaluating-to-unit-rather-than-the-v by cc-by-sa and MIT license