Skip to content

github.com

myeongin edited this page Mar 20, 2016 · 12 revisions

1장 확장 가능한 언어

스칼라 설계와 그 이유를 설명하고 배경, 역사를 설명

scala는 어떤 언어인가?

  • 스칼라는 확장가능 가능한 언어 라는 뜻이다. "Scalable Language" 줄여서 scala 라고 부른다고 한다.
  • 사용자의 요구에 따라 자랄 수 있는 언어로 설계
  • 작은 스크립트 부터 커다란 시스템 구축까지 사용 가능
  • 쉬운 접근성
  • Java 플랫폼에서 실행 가능
  • 모든 자바 라이브러리와 연동 가능
  • 자바 컴포넌트를 한데 묶는 스크립트를 작성할 때 좋다.
  • 커다란 시스템을 구축하거나 재사용 가능한 컴포넌트로 이루어진 프레임워크를 만들 때 더 강점을 발휘
  • 객체지향과 함수형 프로그래밍 개념을 정적타입언어 에 합쳐놓은 언어다.
  • 가독성?이 좋으며 간결하다.

1.1 Scala 확장성

val captial = Map("US" -> "Washington", "France" -> "Parias") 
captial +=  ("Korea" -> "Seoul") 
println(captial("France"))
  • 위 예제는 편리함과 유연성을 동시에 제공
  • 쉽고 간결하다.
  • Map은 libary abstraction 이라서 확장하고 변경 가능하다.
  • HashMap 이나 TreeMap 같은 구체적인 구현을 지정 할 수도 있다.
  • trait를 mixin 할수 있다.
  • map 에 디폴트 값을 지정 할 수도 있다.
  • map 의 method를 오버라이드 가능

새로운 타입을 키워가기

def factorial( x : BigInt) : BigInt = if (x==0) 1 else x * factorial ( x - 1)

  • 이 처럼 Java에서는 불가능 하지만 Scala 에서는 내장타입과 같이 정수 리터럴이나 *, - 등의 연산이 가능하다.
  • 만약 BigInt 클래스가 없더라도 사용자가 별도로 구현 하면 된다.

새로운 제어 키워가기

  • 스칼라는 확장성 원칙을 제어 구조에도 마찬가지로 적용된다.
  • 이런 확장성을 스칼라 API 의 '액터기반 동시성 프로그래밍(actor-based concurrent programming)' API에서 볼 수 있다.
  • 병렬처리 같은 동시성 처리를 위해서는 얼랭의 '액터' 같은 메시지 전달 아키텍처가 더 유용 할 수도 있다.
  • 자바에서는 다양한 스레드 기반 동시성 라이브러리를 제공한다. scala 에서는 그 라이브러리 들을 활용 할 수 있지만 얼랭의 액터 모델을 구현하는 라이브러리를 추가 제공한다.
  • 액터(actor) 는 스레드 위에 구현할 수 있는 동시성 추상화 요소다.
  • 액터 개념은 추후 나올 예정이다. 기본 개념은 메시시를 송신 하고 수신을 기다리지 않고 다음 일을 처리하면서 수신된 메세지들을 비동기로 처리하고 메세지의 형태에 따라 각각 처리하는 개념이다.

1.2 스칼라의 확장성이 가능한 이유

  • 핵심은 객체지향과 함수형 프로그래밍의 조합
  • 여타 언어에서는 객체와 함수가 별개의 개념일 수 있지만 스칼라에서는 함수 값도 객체다.
  • 함수타입은 서브클래스가 상속 할 수 있는 클래스다.

스칼라는 객체지향적이다

  • 객체의 맴버가 아닌 static 필드나 메소드를 허용한다. 처음에는 그리 해롭지 않아 보이지만 여러가지를 복잡하게 만들고 확장성을 제한한다.
  • 반면 스칼라는 순수한 형태의 객체지향 언어다. 모든 값이 객체이며, 모든 연산은 메소드 호출이다.
  • 스칼라에서 1 + 2 라고 쓰면 Int 클래스에서 정의한 +라는 연산이 호출되는 것이다. 1.+(2)
  • 객체를 조합함에 있어서 다른 언어들보다 뛰어나다
  • trait를 통해 자바의 다이아몬드 상속을 피 할수 있다.
  • 자바의 클래스는 여러개의 클래스를 상속받지 못하기 때문에 상속에 상속에 상속을 받는 케이스가 발생 할 수도 있다.

스칼라는 함수형이다

  • 함수형 프로그래밍은 두 가지의 주요 아이디어에 따라 방향이 정해진다.
  • 함수가 1급계층(first class)값이라는 점이다.
  • 함수형 언어에서 함수는 정수나 문자열과 동일한 자격을 갖는 값이다.
  • 함수에서 다른 함수에 인자로 넘길 수 있고 함수 안에서 결과로 함수를 반환 가능하며 함수를 변수에 저장도 가능하다.
  • 함수에서 변수의 값을 지정 하듯이 다른함수의 내부에서 함수를 정의 할 수도 있다.
  • 함수에 이름을 지정하지 않고 함수를 정의 할 수도 있다. (익명함수)
  • 1급 계층 값은 함수는 연산을 추상화하거나 새로운 제어 구조를 만들어 내는데 있어서 좋은 수단이다.
  • 프로그램은 입력 값을 출력 값으로 변환해야 하며, 데이터를 그 자리에서 변경하지 말아야 한다. 즉 SideEffect가 없어야 한다.
  • 예를 들어 자바의 "a.b.c" 라는 문자열에서 ','을 '-' 으로 변경 하려면 s.replace(",", "-")을 사용한다. 이렇게 하면 기존 문자열이 바뀌는 것이 아닌 새로운 문자열이 생성된다. 이런관점에서 자바의 string은 immutable 하다.
  • replace 같은 메소드를 참조투명(referentially transparent) 하다고 한다.
  • 이처럼 scala 에서는 변경 불가능한 리스트, 튜플, 맵, 집합을 제공한다.
  • 함수형 언어는 변경 불가능한 데이터와 참조 투명한 메소드를 장려한다.

1.3 왜 스칼라인가?

스칼라는 호환성, 간결성, 고수준 추상호, 고급 정적 타이핑 이 4가지 강점을 가지고 있다.

scala는 호환성이 좋다.

  • scala를 사용한다면 자바 플랫폼을 떠날 필요가 없다.
  • scala 프로그램은 JVM 바이트코드로 컴파일 되며, 그 프로그램의 실행 성능은 보통 자바 프로그램과 대등하다.
  • scala 코드가 JAVA 필드에 접근하거나, JAVA 클래스를 상속하거나, JAVA 인터페이스를 구현 할 수도 있다.
  • 특별한 문법을 사용하거나 interface 를 별도로 사용하지 않고 별도의 연결코드가 필요치 않다.
  • JAVA 의 타입을 단순히 재사용만 하는 것이 아닌 더 좋게 만들어 사용한다.
  • 예를 들어 scala 문자열은 자신을 정수나 부동소수점 수로 바꾸는 toInt, toFloat를 지원한다.
Integer.parseInt(str);
str.toInt
  • 실제로 JAVA String 에는 toInt 메소드가 없음 에도 불구하고 Scala에서는 가능하다.
  • 이를 암시적 변환(implict conversion) 이라 하며 JAVA 클래스에서 메소드를 찾은 후 없으면 Scala에 있는 StringOps 의 인스턴스로 변환 후 메소드를 찾는다.

스칼라는 간결하다.

  • scala 프로그램은 보통 JAVA 보다 짧다. 보통 10배정도 즐어든다고한다??
  • 느낌상 최소 2~3배는 주는것 같다.
  • 세미콜론(;) 선택적이지만 일반적으로 사용하지 않는다.
  • 별도로 Retrun 을 안해줘도 함수 제일 마지막에 있는 변수를 리턴한다.
class MyClass {
  private int index;
  private String name;
  public MyClass(int index, String name){
    this.index = index;
    this.name = name;
  }
}

Java

class MyClass(index : Int, name : String)

scala

  • scala 클래스는 더 빨리 작성 하고 읽기 쉽다? (생산성이 매우 향상)
  • scala를 잘 알고 있다면 가독성이 매우 빠르겠지만 JAVA 개발자가 본다면 그렇지 않다.
  • 어려운 기술이나 문법이 들어가면 가독성이 매우 좋진 않지만 그래도 JAVA 코드보다는 좋다.
  • 타입추론(type inference)은 이런 간결성을 더욱 더 향상 시켜준다.
  • 의미없이 반복적으로 타입 정보를 사용 할 필요가 없다.
val a = 3
// a는 Int 
val b = 4.0
// b는 Float
val c = a + b
// c는 7.0 Flaot

scala는 고 수준이다.

  • 설계하고 사용하는 인터페이스의 추상화 수준을 높여서 복잡성을 관리할 수 있다.
boolean nameHasUpperCase = flase;
for(int i=0; i< name.length(); ++i) {
  if (Character.isUpperCase(name.charAt(i))) {
    nameHasUpperCase = true;
    break;
  }
}

JAVA

val nameHasUpperCase = name.exists(_.isUpper)

scala

  • JAVA 에서도 표현 할수 잇지만 interface 를 만들고 implement 해야된다. 한마디로 scala 보다 복잡하다

scala 는 정적 타입 언어다. (static type system)

  • 정적타입시스템은 변수나 표현식이 저장하거나 계산하는 값의 종류에 따라 이들을 분류한다.
  • 중첩 클래스와 Generic, 파라미터화한 타입을 허용하며, 교집합을 사용해 타입을 조합할 수도 있다.
  • 추상타입(abstract type)을 사용해 어떤 타입에서 상세 내용을 감출 수도 있다.
  • scala type system은 안전하면서 동시에 사용하기 유연한 인터페이스를 설계할 수 있도록 type을 조합하고 만들어내는데 있어 튼튼한 기초를 제공한다.
  1. 프로퍼티 검증
  • runtime시점에 오류가 없음을 증명 할 수 있다. (compile 시점에 오류를 잡음)
  1. 안전한 리펙토링
  • 만약 정적타입 시스템이 아닌 프로그램에서 파라미터를 하나 더 넣는 리펙토링을 한다면 오류를 잡기 매우 힘들다.
  1. 문서화
  • 타입이 정해져 있고 타입추론을 통해 code를 간결하게 해줌으로 문서의 필요성이 낮아지고 문서도 간결해진다.
val x : HashMap[Int, String] = new HashMap[Int, Sting]()

val x : Map[Int, String] = new HashMap()

1.4 scala의 뿌리

  • scala설계 당시 프로그래밍 언어와 프로그래밍 언어 학계의 아이디어로부터 많은 영향을 받았다.
  • 표먼적으로는 자바와 C# 에서 빌려왔다.
  • scala는 최초의 함수형 언어도 아니고, 최초의 오브젝트 지향, 함수형 프로그램을 접목한 프로그램은 아니지만 프로그래밍 언어 분야 혁신에 기여한 부분은 사실이다.

1.5 결론

  • 스칼라의 가장 어려운 점이라면 타입시스템과 함수형 프로그래밍 일 것이다.

Clone this wiki locally