[4:23 PM] linflus: 오늘은 위키 정리가 애매하면 이 채널에 내가 오늘 뭘 봤다 무슨 내용이었다 내용 요약이라도 올리겠읍니다. [4:23 PM] linflus: 데캠의 노예 스칼라의 노예 선언을 해놓고 너무 나태한 노예질을 하는 것 같아서 [4:23 PM] linflus: ... ----- Tuesday, May 20th, 2014 ----- [3:05 AM] linflus: 오늘의 Scala [3:05 AM] linflus: Martin Odersky(어려우므로 이하 스칼라 아저씨)의 강의를 들었읍니다. [3:05 AM] linflus: 스칼라 아저씨의 강의는 매우 친절! 거북이처럼 느리게 들었더니 프로그래밍의 기초를 배우고 있었읍니다. [3:06 AM] linflus: 오늘 들은 내용의 핵심은 evaluation [3:07 AM] smksyj: 엑 [3:07 AM] smksyj: 쓰다가 잘랐네 [3:08 AM] linflus: ? [3:08 AM] linflus: 얼음 먹으러.. [3:10 AM] linflus: Call by value는 함수 실행 시 argument를 먼저 evaluate [3:11 AM] linflus: Call by name은 함수 body?를 먼저 대체한 다음 값을 evaluate [3:11 AM] linflus: 같은 함수에 대해 Call by value와 Call by name을 단계별로 트레이스하면서 몇단계를 거치는지 열심히 설명하기에 이게 프랙티컬한 측면에서 굉장히 유의미한 것인지 조금 궁금해졌다 [3:12 AM] linflus: finite 할 경우에 그렇다는 이야기 [3:12 AM] linflus: (=call by value로도 terminate call by name으로도 terminate일때) [3:13 AM] linflus: call by value로 terminate일 경우 call by name으로도 terminate임이 보장되지만 그 반대의 경우는 보장되지 않는다 [3:14 AM] linflus: 스칼라는 기본적으로 evaluation에 call by value를 쓴다 [3:15 AM] linflus: 이유는 exponentially 효율적인 경우가 더 많아서라고.. [3:15 AM] linflus: 하지만 call by name을 강제할 수 있따 [3:16 AM] linflus: def sum(x:Int, y: *=>* Int) = x+y [3:16 AM] linflus: _(앗 =>에 bold를 적용했지만 티가 잘 안 나잖아!)_ [3:17 AM] linflus: 어쨌든 => 를 사용하면 y는 call by name으로 evaluation 하겠다는 뜻 [3:17 AM] linflus: 주간회의 세미나에서 얼핏 봤지만 이번 영상을 보면서 스칼라에서 함수 정의하는 문법이 좀 더 눈에 익었다 [3:19 AM] linflus: 아 맞다 call by value가 기본인 이유 중에 스칼라는 imperative하게 사용될 수 있어서 call by value가 기본인 쪽이 사이드 이펙트를 고려할 경우 더 자연스럽다(:question:)는 이유도 있었음 [3:19 AM] linflus: ~오늘의 스칼라 끝~ [3:19 AM] smksyj: 고생하셨습니다 [3:20 AM] linflus: 애매한 내용 지적은 감사합니다 [3:20 AM] linflus: 해주시면 내일 월급도둑질 하면서 봄.. [3:20 AM] smksyj: 그럼 call-by-value로 할 때는 [3:20 AM] smksyj: 어떤 식으로 함수 정의를 하면 되나요? [3:20 AM] linflus: ?! [3:20 AM] linflus: 그냥 쓰면 call by value.. [3:20 AM] linflus: 그니까 위에 sum에서 x는 call by value y는call by name [3:20 AM] linflus: 이 얘기가 아닌가 [3:21 AM] linflus: terminate 관련된 얘긴가?! [3:21 AM] linflus: 그건 좀 더 공부해야함!!ㅋㅋㅋ [3:24 AM] smksyj: 아 [3:24 AM] smksyj: ㅇㅇ [3:24 AM] smksyj: 그냥 쓰면 되는군 ----- Wednesday, May 21st, 2014 ----- [1:07 AM] smksyj: @linflus: 혹시 오늘도 오늘의 스칼라는 연재 하나요? [1:07 AM] linflus: 머리 감고 와서 할듯? [1:07 AM] linflus: 머리 감고 와서 영상을 본 뒤.. [1:07 AM] lyuha: 자고 내일 아침에 봐야지... [2:25 AM] linflus: 아직 다 안 봤지만 오늘의 뻘소리 : 스칼라 아저씨는 x를 [iks]라고 발음한다. 그게 독일식 발음인듯??? [3:01 AM] linflus: 아주 짧은 오늘의 스칼라 [3:01 AM] linflus: 조건문이 나왔다. 사실 조건문은 어떻게 보면 매우 익숙한 내용인데... [3:02 AM] linflus: 아저씨는 자바의 조건문과 비슷하지만 statement가 아닌 expression에 대해 사용한다고 설명 [3:03 AM] linflus: Boolean 값에 대해서도 설명했다 [3:04 AM] linflus: 그리고 반가운(?) Short-circuit evaluation에 대해서도.. 이건 새싹 수업할때도 조건문 부분에서 하는 내용이지만 [3:05 AM] linflus: a || b 에서 a가 true일 경우 b 값과 상관없이 expression 값은 true로 evaluation 할 수 있기 때문에 b 값을 evaluation 하지 않고 [3:06 AM] linflus: 마찬가지로 a && b에서는 a가 false일 경우 b 값과 상관없이 expression 값을 false로 evaluation 할 수 있기 때문에 b 값을 evaluation 하지 않고 [3:07 AM] linflus: 새싹 수업할때는 C언어 조건문을 다루는 부분이라 true || a++ 이런 식의 문장을 주고 a++가 evaluation 되지 않기 때문에 a 값이 증가하지 않는다는 걸 샘플로 보여주곤 했는데 [3:08 AM] linflus: 이 강의는 스칼라로 알아보는 functional programming에 대한 내용이라 저런 mutable variable은 다루지 않는다 [3:10 AM] linflus: 대신에 terminate 되지 않는 expression을 뒤에 두고 evaluation하지 않는 것을 샘플로 설명하더라.. [3:10 AM] linflus: 조건문 다음에 value definition에 대한 부분이 나왔다 [3:13 AM] linflus: 어제 본 부분에서는 call by value와 call by name 즉, argument의 evaluation에 대한 내용을 다루었는데 value definition 부분에서는 definition에 대한 같은 접근을 다루고 있다 [3:14 AM] linflus: def는 by name / val은 by value [3:16 AM] linflus: val x = sum(2, 3) //이 때 sum은 두 argument의 합을 반환하는 function [3:16 AM] linflus: 이라면 val을 사용한 definition은 by value이므로 val x = 5로 evaluation 된다 [3:16 AM] linflus: terminate되지 않는 경우를 생각해보면 [3:16 AM] linflus: def loop: Boolean = loop [3:17 AM] linflus: 와 같은 terminate 되지 않는 function loop가 있을 때 [3:17 AM] linflus: def x = loop [3:17 AM] linflus: 라고 정의하면 by name으로 정의하기 때문에 x를 evaluation하지 않는다 [3:18 AM] linflus: 하지만 val x = loop 라고 정의하면 by value로 정의하기 때문에 x를 evaluate하려고 하고 infinite loop에 빠지게 된다 [3:19 AM] linflus: 스칼라 아저씨가 친절히 쉘에 해당 expression을 쳐서 와장창... 뻗는 모습을 보여주심 [3:19 AM] linflus: 영상 후반부에는 퀴즈 내고 그거 설명하는 게 거의 전부였는데 사실 되게 간단한거 [3:19 AM] linflus: and(x, y) == x && y [3:20 AM] linflus: or(x, y) == x || y [3:20 AM] linflus: 가 성립되는 and와 or function을 &&, || 연산자 없이 정의해보라는 것이다 [3:20 AM] linflus: 오늘 조건문 배웠으니까 그냥 그거 쓰면 된다 [3:21 AM] linflus: 근데 이 내용을 굳이 쓰는 이유가 [3:21 AM] linflus: def and(x: Boolean, y: Boolean) = if(x) y else false [3:22 AM] linflus: def or(x: Boolean, y: Boolean) = if(x) true else y [3:22 AM] linflus: 이렇게 정의하면 트랩카드라서 [3:23 AM] linflus: 왜냐면 저 경우엔 y가 call by value라서 short circuit evaluation 하지 않는다 [3:23 AM] linflus: def and(x: Boolean, y: => Boolean) = if(x) y else false [3:23 AM] linflus: def or(x: Boolean, y: => Boolean) = if(x) true else y [3:23 AM] linflus: 위와 같이 두번째 argument y에 대해 call by name을 강제해야 한다 [3:24 AM] linflus: 직접 스칼라 코드를 짜게 되면 이런 점을 간과해서 많은 시간을 소비하게 되리라는 불길한 예감과 함께 오늘의 스칼라 끝끝 [3:25 AM] linflus: 그리고 오늘의 뻘소리 2 : 이번편은 영자막이 없어서 당황과 분노 ----- Thursday, May 22nd, 2014 ----- [2:26 AM] linflus: 오늘의 스칼라 [2:27 AM] linflus: 는 간단한 예제 구현과 그에 대한 설명이라서 IDE 셋팅을 했다 [2:27 AM] linflus: 난 Intellij를 사용하기로 함 [2:28 AM] linflus: 예제는 newton's method를 이용하여 제곱근 구하는 함수 만들기였음 [2:28 AM] linflus: newton's method나 제곱근 구하기가 스칼라랑 딱히 상관이 없으니 이 부분 설명은 패스 [2:28 AM] linflus: 궁금하다면 검색 혹은 수치해석과 그래픽스가 여러분을 환영 [2:30 AM] linflus: 첫 영상은 대체로 같이 구현해보는 시간이라 크게 적을 것이 없다... [2:30 AM] linflus: 제곱근 구하는 함수를 재귀적으로 호출하게 되는데 [2:31 AM] linflus: 그동안 오늘의 스칼라에 쓴 함수들 보면 바로 위에 썼던 [2:31 AM] linflus: def and(x: Boolean, y: => Boolean) = if(x) y else false [2:31 AM] linflus: 만 하더라도 return type을 명시적으로 정의해주고 있지 않다 [2:31 AM] linflus: 보통 return type은 optional [2:31 AM] linflus: 하지만 재귀적으로 호출하는 함수의 경우 명시적 return type의 정의가 필요하다 [2:36 AM] linflus: 이 부분에 대한 설명은 나중에 스칼라의 type inference에 대해 찾아보고 좀 더 자세히 쓸 예정 [2:37 AM] linflus: 그리고 바로 다음 영상에서는 이미 짰던 제곱근 구하는 함수를 좀 더 깔끔하게 바꾸면서 block과 scope에 이야기 함 [2:38 AM] linflus: block은 아마 따로 설명 듣지 않아도 다들 코드 훑으면 감으로 파악할 수 있는 그런 부분 [2:39 AM] linflus: { ... } 처럼 중괄호로 감싸줘서 만들 수 있다 [2:42 AM] linflus: val x = 1 val block = { val x = 2; val y = 1; x+y } + x [2:44 AM] linflus: block 내부에서 정의된 symbol은 block 외부에서 접근할 수 없고 [2:45 AM] linflus: symbol이 겹칠 경우 block 내부의 정의가 우선이다 [2:45 AM] linflus: 즉, 위 코드에서 block 밖에서 y에 접근하는 것은 불가능 [2:46 AM] linflus: 그리고 block의 evaluation 값은 4 [2:46 AM] linflus: =(2+1)+1 [2:46 AM] linflus: 끝부분에 세미콜론 얘기 나오는데 스칼라에서 식 끝의 세미콜론은 optional이다 [2:47 AM] linflus: 필수인 경우는 한 줄에 여러 식을 함께 쓸 경우 [2:47 AM] linflus: 위에 쓴 val x = 2; val y = 1; x+y 처럼 [2:48 AM] linflus: 세미콜론이 필수가 아니라서 하나의 긴 식을 여러줄에 나눠 썼을 때 원하는대로 evaluation 되지 않을 수 있다 [2:48 AM] linflus: expr1 + expr2 [2:49 AM] linflus: 일 경우 두 식을 각각 evaluation 하는 경우가 생김 [2:49 AM] linflus: 이 때 쓸 수 있는 방법은 [2:49 AM] linflus: (expr1 + expr2) [2:49 AM] linflus: 괄호 짱짱맨b [2:49 AM] linflus: 혹은 [2:50 AM] linflus: expr1 + expr2 [2:50 AM] linflus: 오늘의 스칼라는 끝 [2:50 AM] linflus: 아 오늘은 세시에 잘 수 있다... [2:54 AM] lyuha: 뭐랄까 여러가지 짬뽕된 느낌... [2:56 AM] linflus: 스칼라가? [2:56 AM] linflus: 아니면 적어둔 강의 내용이? [2:56 AM] lyuha: 스칼라요 [2:57 AM] linflus: pure functional language가 아니라서 그렇게 느끼는 것일지도.. [2:57 AM] linflus: 하지만 강의 영상은 스칼라로 배워보는 functional programming이라 functional한 측면에 focusing하고 있다고 생각하는데.. [2:58 AM] linflus: 사실 이건 딴소리지만 진정한 짬뽕의 맛은 ruby에서 느낄 수 있습니다 [2:58 AM] linflus: (라고 개인적으로 생각...) ----- Friday, May 23rd, 2014 ----- [3:05 AM] linflus: 오늘의 스칼라 [3:05 AM] linflus: 는 Tail recursion [3:07 AM] linflus: 오 [3:08 AM] linflus: Tail recursion 관련해서 위키피디아를 한번 찾아봤는데 한국어 페이지가 없다 [3:08 AM] linflus: 역시 검색은 한국어로 하면 안돼... 이건 이 채널 주제랑은 다르지만 어쩌면 날 검색대행자로 써먹는 분들은 평소에 네이버에 한글로 검색해서 아무것도 못 찾는 걸지도... [3:12 AM] linflus: 흠 이게 사실 난 되게 쓸 게 없다고 생각했는데 왜냐면 Tail recursion이 스칼라에만 있는 것도 아니고 해서 [3:12 AM] linflus: 하지만 생각해보면 이 세상에 오직 스칼라에만 있는게 몇개나 된다고.. [3:12 AM] linflus: 아무튼 그런 의미에서 간단히 Tail recursion 이야기 [3:14 AM] linflus: 이거 관련해서는 얼마 전에 #offtopic쪽에서도 얘기 했었는데.. [3:15 AM] linflus: 함수 호출하면 스택에 parameter 등 함수 호출과 관련된 데이터를 쌓는다 [3:16 AM] linflus: 리턴하면 쌓았던 데이터를 빼고 [3:16 AM] linflus: 라고 말하고 보니 쌓고 빼고 이 단어가 마음에 안들지만 아무튼 지금 크게 중요한 게 아니니 패스 [3:18 AM] linflus: 만약 a 함수 실행 중에 b 함수를 호출하면 a 데이터가 스택에 쌓였다가 b 호출할 때 b 데이터를 스택에 쌓고 b 리턴되면 b 데이터를 빼고 a 리턴되면 a 데이터를 빼고 [3:19 AM] linflus: 근데 재귀함수면 종료조건에 도달하기 전까지 리턴이 안되고 종료조건 도달해야지만 리턴리턴리턴되니까 데이터를 계속 쌓기만해서 스택 잡아먹음 [3:25 AM] linflus: 이걸 재귀호출 이후 다른 연산이 없도록 tail recursive하게 짜면 스택프레임을 겁내 양산하지 않고 재활용한다 [3:25 AM] linflus: 재귀 호출 이후 다른 연산이 없도록 이란 말은 사실 예제를 보면 한큐에 알 수 있다 [3:25 AM] linflus: 재귀계의 국민예제 factorial 나와라 얍! [3:26 AM] linflus: def factorial(n: Int):Int = if(n == 0) 1 else n * factorial(n-1) [3:27 AM] linflus: 이 경우 종료조건 도달하기 이전에 factorial(n-1)을 재귀적으로 호출한 뒤 n과 곱하는 연산이 필요함 => tail recursive하지 않음 [3:29 AM] linflus: def factorial(n: Int):Int = { def sub(result: Int, n: Int): Int = if(n == 0) result else sub(n * result, n-1) sub(1, n) } [3:30 AM] linflus: 이 경우 sub(n*result, n-1)을 재귀적으로 호출한 뒤 다른 연산을 수행하지 않음 => tail recursive [3:30 AM] linflus: 사실 영상을 하나 더볼까 했었지만 네시엔 자야겠기에 끝.... [12:39 PM] lyuha: tail recursive 반복적인 프로세스로 진행하는 재귀함수 인건가요.? ----- Saturday, May 24th, 2014 ----- [3:28 AM] linflus: 오늘은 ctrlcv 끝나고 늦게 들어와서 [3:28 AM] linflus: 스킵하긴 뭐하고 해서 [3:28 AM] linflus: http://scalatutorials.com/tour/ Interactive Scala Tutorial [3:28 AM] linflus: 이걸 쭉 훑으면서 따라감 [3:28 AM] linflus: 지금 보고있는 coursera 강의는 스칼라 언어 문법 강의가 아니라 스칼라로 설명하는 함수형 프로그래밍 이라서 [3:29 AM] linflus: 내용에 함수형 프로그래밍 개념도 많이 섞여있고 스칼라도 굉장히 함수형 프로그래밍 언어스럽게 쓰고있는데 [3:29 AM] linflus: 저 튜토리얼은 그런거 없어서 새삼 아 그렇군 내가 듣고있는 강의가 함수형 프로그래밍 강의였군 하는 걸 깨달음 ----- Sunday, May 25th, 2014 ----- [4:51 AM] linflus: 오늘의 스칼라 [4:52 AM] linflus: 는 Higher order function에 대한 내용 [4:53 AM] linflus: 아저씨 말로는 함수형 프로그래밍에서 중요한 개념이라고 한다 [4:54 AM] linflus: 대충 검색해보면 cs에서만 쓰이는 용어는 아니고 원래 mathematics에서 쓰이던 용어인듯 [4:54 AM] linflus: 아 [4:55 AM] linflus: 그러고보니 당연히 그런듯 [4:55 AM] linflus: order란 말이 한국어로 몇차 할때 차였던 것 같은데?!?! [4:56 AM] linflus: 그럼 한국어로 고차함수란 뜻인가? [4:57 AM] lyuha: 대충... [4:57 AM] lyuha: 그런거같네요 [4:57 AM] linflus: ㅋㅋㅋ아 그런거였네 [4:58 AM] linflus: 암튼 다음 두 조건 중 하나를 만족하는 경우 higher order function [4:58 AM] linflus: 1. 함수를 parameter로 받거나 [4:59 AM] linflus: 2. 함수를 return 하거나 [5:01 AM] linflus: 크.. 사실 난 math하는 사람이 아니니깐 higher order function 보다는 first class function 얘기를 하는 게 좋을 것 같다 [5:02 AM] linflus: first class function은 function을 first class object로 취급하겠다는건데 [5:02 AM] linflus: 학교 커리큘럼 따라서 C C++ Java 대충대충 짜다가 Javascript 책 보기 시작하고 처음에 되게 골때리는 부분이 여기였던 것 같다 [5:02 AM] linflus: 이게 말도 생소하고 또 번역하면 일급객체 이런 식이 돼서... [5:03 AM] linflus: 일급객체... 흠좀... 뭔가 급이라는 말이 갖는 그 느낌이.....흠.... [5:03 AM] lyuha: 아.. [5:03 AM] lyuha: 일급객체 하면 [5:03 AM] lyuha: 느낌 이상하고 뭔가 [5:04 AM] linflus: 하지만 사실 심플하게 생각하면 그냥 function을 다른 function의 argument로 넘겨줄 수도 있고 return 값으로 쓸 수도 있다 [5:04 AM] linflus: 는 것. 찾아보면 다들 이렇게 설명하지만 읽고나면 그래서 왜 이게 일급인지 이해할 수 없기때문에 처음엔 난감 [5:04 AM] linflus: 번역이 잘못했네 [5:04 AM] lyuha: first class object 라는 건 [5:05 AM] lyuha: 인자와 리턴값으로 쓸수 있다 정도인가요. [5:05 AM] linflus: 앗 정의를 그렇게 내리면 좀 허접한 정의가 되는듯 [5:05 AM] linflus: c c++ java에서 흔히 코딩하던 방식과의 차이라서 그렇게 얘기한것뿐 [5:08 AM] linflus: 틀린 말이라기보단 음... first class object가 뭐다 하려면 사실 [5:08 AM] linflus: 인자와 리턴값으로 쓸 수 있다는 얘기 한줄만 하는 것보다는 ~ class object 얘기 자체를 하는게 좋을 것 같기도 하고.. [5:09 AM] lyuha: 뭔가 조건 4개가 있는데 [5:09 AM] lyuha: 그중 2개가 저것 이긴 하네요 [5:12 AM] linflus: 크.. 그걸 다 묶어서 깔끔하게 정의하는 게 더 좋은데 대체로 아래의 조건을 만족하면 first class object다 이런식으로 설명하네.. [5:13 AM] linflus: 위키피디아를 보면 애초에 처음 그 개념을 언급한 사람이 [5:13 AM] lyuha: 위키피디아에서 정의한건 2개는 보자마자 감이 안 오네요. [5:13 AM] linflus: 알골에서의 객체를 구분지어 말하면서 나온 거라 그런지 [5:14 AM] linflus: 엄밀하고 깔끔한 그런 느낌은 기대하면 안될 것 같기도... [5:15 AM] linflus: 이게 어쩌면 수학쟁이가 만든 말이 아니라 컴퓨터쟁이가 만든 말이라 그런것이 아닐까하는 슬픈 추측을 잠시 했으나 찾아보니 그는 수학쟁이였읍니다 [5:15 AM] linflus: 감이 안 온다는 2개는 어떤건가요? [5:17 AM] lyuha: 한국어 위키에 설명된 변수나 데이터 구조안에 담을 수 있다. 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다. [5:19 AM] linflus: 일단 변수나 데이터 구조한에 담을 수 있다 [5:19 AM] linflus: 이건 말 그대로예요 [5:19 AM] lyuha: assigned to a variable [5:19 AM] lyuha: 이 의미인가요 [5:19 AM] linflus: 네 [5:19 AM] linflus: 이것도 번역이 잘못했나 [5:19 AM] linflus: ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ [5:19 AM] lyuha: ㅋㅋㅋㅋㅋ [5:19 AM] lyuha: 안에 담을 수 있다보단 [5:19 AM] lyuha: 안에 담을 수 있다.... [5:19 AM] lyuha: 뭔가 맞는 번역이긴한데 [5:20 AM] lyuha: 봤을때는 뭔지 고민했네요 [5:20 AM] linflus: 할당에 사용된 이름과 관계없이 고유한 구별이 가능하다 이건 뭘 번역한거지... [5:21 AM] lyuha: 모르겠어요...그건... [5:21 AM] linflus: 딱히 영문 문서들에 정의내릴때 그런 표현은 안 쓰는 것 같은데.. [5:21 AM] linflus: 더 찾아보고 무슨 의도인지 알것같으면 여기 멘션걸고 쓸게요 [5:22 AM] linflus: 정의할때 꼭 필요한 조건이라기보다 그 페이지 정리하던 사람이 부연해서 쓴 것 같은 느낌이라 [5:22 AM] lyuha: 네.. [5:22 AM] linflus: 아무튼 다시 원래대로 돌아가서 [5:23 AM] linflus: 자바스크립트에서 흔히 first class function을 느껴보기 좋은 경우가 콜백함수 parameter로 넘겨줄때 [5:23 AM] linflus: c만 짜던 사람한테는 함수포인터 얘기를 하게 됨 [5:25 AM] linflus: 강의에서는 간단한 예제를 사용했는데 [5:25 AM] linflus: def sumInts(a: Int, b: Int): Int = if(a>b) 0 else a + sumInts(a+1, b) [5:26 AM] linflus: 이게 a와 b 사이에 있는 정수를 다 더해서 리턴하는 함수 [5:26 AM] linflus: 이때 a와 b사이에 있는 정수들을 모두 3제곱한 채 더하고 싶으면 [5:27 AM] linflus: `def cube(x: Int):Int = x * x * x` (edited) [5:27 AM] linflus: 오.. 크 수정했다 (edited) [5:28 AM] linflus: def sumCubes(a: Int, b: Int):Int = if(a>b) 0 else cube(a) + subCubes(a+1, b) [5:28 AM] linflus: 근데 function을 parameter로 넘겨줄 수 있으니 굳이 매번 이렇게 만들 필요가 없음 [5:29 AM] linflus: def sum(f: Int => Int, a: Int, b: Int):Int = if(a>b) 0 else f(a) + sum(f, a+1, b) [5:29 AM] linflus: def id(x:Int): Int = x [5:29 AM] linflus: `def cube(x:Int):Int = x * x * x` [5:29 AM] linflus: 해서 [5:29 AM] linflus: sum(id, a, b) [5:29 AM] linflus: sum(cube, a, b) [5:29 AM] linflus: 이런식으로 호출해주면 된다 [5:30 AM] linflus: f: Int => Int 이 부분은 f라는 function이 Int 값 하나를 parameter로 받아 Int를 반환하는 함수라는 뜻 [5:30 AM] linflus: 이걸 이제 익명함수를 쓰면 [5:31 AM] linflus: sum(x => x, a, b) [5:31 AM] linflus: `sum(x => x * x * x, a, b)` [5:31 AM] linflus: 이렇게 쓸 수 있다. id, cube같은 함수 정의도 필요 없음 [5:31 AM] linflus: parameter로 한번 넘기고 말 function이라면 익명으로 쓰는게 나은것같다 [5:32 AM] linflus: 오늘의 스칼라는 끝 (edited) [5:32 AM] linflus: 내일 볼 영상이 기대된다. 주제가 Currying이라서... [5:32 AM] linflus: 전에 분명 읽어봤는데 뭔 말인지 기억이 안 나는 Currying...... [5:32 AM] lyuha: 언제나 [5:33 AM] lyuha: 올라오면 두근두근하면서 보게되는 #scala [5:33 AM] linflus: 늦게까지 안 자네요!! [5:33 AM] linflus: 그나저나 ㅋㅋ [5:33 AM] lyuha: 뜨끔... [5:33 AM] lyuha: 과제 한다는 이유로 안 자다가 [5:33 AM] lyuha: 과제 진행도는 0.... [5:34 AM] linflus: ㅠㅠㅠㅠㅠㅠㅠ [5:34 AM] linflus: 과제 시즌.. [5:34 AM] lyuha: 과제는 [5:34 AM] lyuha: 시즌이 없습니다 [5:34 AM] lyuha: 안 나오는 시즌이 존재할 뿐이죠 [5:34 AM] linflus: ㅋㅋㅋㅋㅋㅋ [5:34 AM] lyuha: ㅋㅋㅋㅋ..... [5:34 AM] linflus: 그런가... [5:34 AM] linflus: 하긴 플젝이 시즌이고 과제는 조금씩 자주 나왔던 것 같네요 [5:34 AM] lyuha: 시험 기간 / 방학기간.... [5:34 AM] linflus: 하지만 진짜 시즌이 없는 것은 출근입니다.......망 [5:35 AM] lyuha: ...아.... [5:35 AM] lyuha: 간접체험 중이죠 ... [5:35 AM] lyuha: 시즌없는 직장... [5:35 AM] linflus: 학부시절에 더 많은 꿀을 빨고 졸업하길 바라요.. [5:35 AM] lyuha: 졸업이 아직 멀답니다. 제 머릿속에선 [5:35 AM] lyuha: 실제로도 멉니다! [5:35 AM] linflus: 졸업보다 군대가 가까울 나이라.. [5:35 AM] linflus: 1학년때 너무 열심히 안해도 돼요 [5:36 AM] lyuha: 군대라니.... [5:36 AM] lyuha: 신검도 아직 안 받았다고요..ㅠㅠ [5:36 AM] linflus: 대충하라는 말이라기보단 음.. 과제 하나하나에 목매다 진짜 하고싶은게 멀어질 수 있다?! [5:36 AM] linflus: 이런 느김 [5:36 AM] lyuha: 그런것보단 [5:36 AM] lyuha: 과제 펴놓고 딴짓부터 그만해야죠... [5:36 AM] linflus: ㅋㅋㅋㅋ그건 누구나 하는거라 [5:36 AM] lyuha: 과제 하나하나 목 매는 스타일도 아니고. [5:36 AM] lyuha: 넘어가면 넘어가고. [5:36 AM] lyuha: 뭐 이런느낌이라 이번 학기는... [5:38 AM] linflus: ㅋㅋㅋㅋ아무튼 과제중이라니 너무 방해하면 안될것같은 느낌 [5:38 AM] linflus: 난 이제 자러... [5:38 AM] linflus: 과제 얼른 마치고 자러가요!! [5:39 AM] lyuha: 방해해도 괜찮습니다 ----- Monday, May 26th, 2014 ----- [12:38 AM] smksyj: 오늘의 scala? [12:39 AM] smksyj: currying은 그렇게 특이한 건 아니지 싶은데 [12:39 AM] smksyj: 내가 알기로는 [12:39 AM] smksyj: 이미 있는 함수에 [12:39 AM] smksyj: 부분 인수를 적용해서 [12:40 AM] smksyj: 새 함수를 만드는 걸 [12:40 AM] smksyj: currying이라고 하는 걸로 알고 있는데 [12:40 AM] smksyj: scala에서 지원하고 haskel에서 지원하고 [12:40 AM] smksyj: function add(a, b) { return a + b; } [12:40 AM] linflus: 오 [12:40 AM] smksyj: 이럴 때 [12:40 AM] linflus: 특이해서 기대된다고 쓴 적 없음 [12:41 AM] smksyj: 그렇군 [12:41 AM] linflus: 분명히 봤는데 뭐더라 해서 기대되는것뿐 [12:41 AM] linflus: ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ [12:41 AM] smksyj: function addOne(value) { return add(1, value); } [12:41 AM] smksyj: 이런 거? [12:41 AM] smksyj: 해서 addOne(10) [12:42 AM] smksyj: 이렇게 쓰는 걸로 기억하는데 [12:44 AM] lyuha: 특이하네요 [12:44 AM] lyuha: 특이해요! [12:44 AM] smksyj: ㄷㄷ [12:45 AM] smksyj: 개인적으로는 왜 쓰는지나 쓰면 뭐가 좋은지 등을 잘 모르겠음 [12:46 AM] smksyj: 그래서 오늘의 linflus가 정리해 주는 걸 기대해 봐야지 [12:46 AM] smksyj: 두근두근 [12:46 AM] lyuha: 두근두근 [12:46 AM] lyuha: 여기 scala는 두근두근하ㅈ [3:23 AM] linflus: 오늘의 스칼라 [3:23 AM] linflus: 는 어제 말한대로 Currying [3:24 AM] linflus: 음식얘기가 아니라는 드립인지 아닌지 모르겠는 멘트로 시작한 강의... [3:24 AM] linflus: Currying은 한줄로 심플하게 말하면 multiple argument를 받는 function을 바꾸는 것 [3:24 AM] linflus: 뭐로? [3:24 AM] linflus: single argument를 받는 function의 chain으로 [3:25 AM] linflus: function의 chain이란 말을 갑자기 쓰는게 애매한가.. [3:27 AM] linflus: 위에 민관이가 말한 경우를 보면 [3:31 AM] linflus: def add(a:Int, b:Int):Int = a + b [3:31 AM] linflus: 는 a, b 두개의 argument를 받고있지만 아래에서는 [3:32 AM] linflus: def addOne(value:Int):Int =add(1, value) [3:32 AM] linflus: 해서 addOne 함수의 경우 single argument를 받음 [3:32 AM] linflus: 말한대로 currying이 뭐다 자체는 진짜 이게 끝인듯? [3:32 AM] linflus: 근데 currying을 쓸거면 저런식으로 안 쓰겠지 싶은 생각은 듬 (edited) [3:33 AM] linflus: 크.. [3:33 AM] linflus: 단어를 찾기 어렵군.... [3:38 AM] linflus: ```def add(a:Int, b:Int):Int = a + b def mul(a:Int, b:Int):Int = a * b def execute(f: (Int, Int) => Int)(a:Int, b:Int):Int = f(a, b) execute(add)(1, 2) execute(mul)(1, 2) ``` (edited) [3:39 AM] linflus: 비슷한 예제라면 차라리 이런쪽을 들고오고 싶은데.. [3:39 AM] linflus: 물론 이 경우엔 execute(add)(1,2)에서 뒤에 (1,2) 넘겨주는 부분은 single argument가 아니지만 [3:41 AM] linflus: 사실 좀 궁금한건 그럼 저기서 execute(add)로 바꾸는 부분까지만 currying이라는 건지 그게 궁금.. 대충 내가 이해하기론 그런데.. [3:42 AM] linflus: 그 부분은 추후 좀 더 알아보기로 하고 Currying 써서 좋아보이는 건 중복되는 부분을 제거하고 일반화 시킬 수 있다는거? [3:42 AM] linflus: 위에 사실 코드가 쓰다만 셈이 됐는데 [3:42 AM] smksyj: 특정 함수에서 인자 일부를 고정시켜서 새 함수를 만드는 것을 currying이라고 하는 거 아냐? [3:43 AM] smksyj: def execute 만든 부분이 [3:43 AM] smksyj: currying 적용시킨 것 같은데 [3:43 AM] linflus: ㅇㅇ 그니까 거기까지만 currying인게 맞나 [3:43 AM] linflus: 그게 궁금 [3:43 AM] smksyj: 내가 알기론 그래 [3:43 AM] linflus: 아하 그렇군.. 땡큐 ㅋㅋ [3:43 AM] linflus: execute((x, y) => x+y)(1, 2) [3:43 AM] linflus: execute((x, y) => x*y)(1, 2) [3:44 AM] linflus: 이렇게 써주면 쓸데없이 add, mul function을 정의할 필요가 사라짐 [3:44 AM] linflus: Currying이 늘 좋으냐고 하면 그건 아니라고 보고.. [3:45 AM] linflus: strategy pattern 쓰는 느낌이란 생각도 들었는데... [3:46 AM] linflus: 이 정도로만 이점을 설명하는게 내 얄팍한 시야 내에서 설명하는 것일 수 있음 [3:47 AM] linflus: 오늘의 스칼라는 끝. [3:47 AM] smksyj: ... [3:47 AM] smksyj: 잠은 언제들 자는 거지 [3:47 AM] smksyj: 김태진도 지금 깨어 있던데 [3:47 AM] linflus: 아마 내일 내용이 앞에 봤던 두 영상 내용을 다른 예제 하나로 더 보는거라 [3:47 AM] lyuha: ...오전에요? [3:47 AM] linflus: 설명이 더 있을 수도 있다는 생각은 듬 [3:47 AM] smksyj: linflus의 출근시간이 오후일 리는 없을테고 [3:47 AM] linflus: 난 원래 세시에 잠 [3:47 AM] linflus: 오늘은 네시에 자니까 내일 피곤하겠지 [3:48 AM] smksyj: ... [3:48 AM] linflus: 오늘의 스칼라 시작하면서 네시에 자는 날이 많아서 [3:48 AM] linflus: 회사에선 거의 멍때리는듯 [3:48 AM] lyuha: .... [3:48 AM] smksyj: 원준이는 언제 수업인지 모르겠군 [3:48 AM] lyuha: 12시요! [3:48 AM] lyuha: 그니까 느긋하죠 [3:49 AM] smksyj: ... [3:49 AM] lyuha: 아 맞다 접속한 사람들 뜨지.... [4:08 AM] smksyj: 헉 근데 이 채널은 3명 뿐인 건가? [4:08 AM] lyuha: 그렇게 되네요... [4:08 AM] smksyj: ... 남이 나 대신 스터디 해 주는 [4:08 AM] smksyj: 이렇게 좋은 채널을 두고 [4:08 AM] lyuha: ㅋㅋㅋㅋ [4:08 AM] lyuha: 진짜 적절합니다 비유가 [4:09 AM] lyuha: 아 위에꺼 다 사라져간다 [4:09 AM] smksyj: 업데이트 빈도도 매일매일이고 [4:09 AM] smksyj: 정말 좋은 채널인데 [4:09 AM] smksyj: /애도 [4:09 AM] lyuha: 가끔 맥앱은 위에를 짤라버려서 refresh는 위대합니다(?) ----- Yesterday May 27th, 2014 ----- [3:03 AM] linflus: 오늘의 스칼라 [3:03 AM] linflus: 는 어제 말한대로 example인데 음... [3:03 AM] linflus: 그걸 직접 짜보는 데 의의가 있고 짜본것을 설명하는데 의의가 있는 영상이 아니었다 [3:04 AM] linflus: 여기에 옮길만한 말은 Currying의 이점에 대한 것인데 [3:04 AM] linflus: 스칼라 아저씨도 abstract와 재사용에 의의가 있다고 함 [3:05 AM] linflus: 그리고 짱짱 abstraction이 꼭 옳은 것은 아니라는 말도 덧붙임 [3:05 AM] linflus: 때때로 concrete한 게 더 적절할 때가 있으나 abstraction techniques를 알아둬야 한다고 [3:06 AM] linflus: 그 다음 영상은 짤막한 스칼라의 syntax 리뷰였다 [3:06 AM] linflus: EBNF로 스칼라 문법을 설명했다 [3:06 AM] linflus: Linflus(은)는 지금 하고있는 것이 #scala인지 #compiler인지 혼란스러웠다 ! [3:07 AM] linflus: 내가 보는 것은 의미가 있었으나 그것도 여기 다 옮겨적을 내용은 아니라서 패스 [3:07 AM] linflus: 어쩐지 하나 더 봐야할 것 같아서 다음 영상도 봤다. 두번째 영상이 엄청 짧긴 했지만 영상 세개나 본 날은 처음.. [3:07 AM] linflus: 오늘은 일찍 보기 시작해서 가능한 일이군.. [3:08 AM] linflus: 드디어 Class가 나왔는데 스칼라로 처음 프로그래밍을 배우는 사람이라면 모르겠으나 [3:08 AM] linflus: 굳이 Java 아니더라도 기존 문법상 class를 지원하는 언어들을 사용해본 사람이라면 [3:09 AM] linflus: 그냥 스칼라의 class는 immutable class여 [3:09 AM] linflus: 하고 생각하면 될 것 같은 내용이었다 [3:09 AM] linflus: 그래도 예제가 없으면 섭섭하니까 예제... [3:10 AM] linflus: 이건 새로 짜와야한다. 왜냐면 영상 예제는 분수라서 그냥 여기에 샘플로 던져놓기엔 좀 읽기 짜증난다. [3:15 AM] linflus: c++ class의 단골예제 Complex 소환! [3:15 AM] linflus: ```class Complex(a:Int, b:Int) { def real = a def imaginary = b def add(that: Complex) = new Complex(real + that.real, imaginary + that.imaginary) def neg = new Complex(-real, -imaginary) def sub(that: Complex) = add(that.neg) override def toString = real + " + " + imaginary + "i" } ``` [3:17 AM] linflus: ```val a = new Complex(1, 3) //a: Complex = 1 + 3i val b = new Complex(4, 5) //b: Complex = 4 + 5i a.add(b) // Complex = 5 + 8i b.add(a) // Complex = 5 + 8i a.sub(b) // Complex = -3 + -2i b.sub(a) // Complex = 3 + 2i ``` [3:18 AM] linflus: 스칼라로 functional programming 할 경우 mutable variable로 상태를 갖는 게 아니기때문에 메서드들이 모두 새 instance를 반환하고 있음 [3:18 AM] linflus: 이게 포인트라고 생각하고.. [3:18 AM] linflus: 그 외의 부분은 다른 것과 다른게 없다.. [3:18 AM] linflus: 오버라이드 할때는 override def라고 씀 [3:18 AM] linflus: 아마 이제부터 본격적으로 코드를 짜게될 것 같다 [3:19 AM] linflus: 그래서 intellj를 적극적으로 쓰려고 하는데 intellj 스칼라 플러그인에서 evaluation worksheet이 제대로 동작하지 않는다 [3:19 AM] linflus: 버그가 고쳐졌다는 버전보다 상위 버전을 쓰고있는데.. 버그가 돌아오셨나? 아윌비백? [3:19 AM] linflus: 아무튼 오늘의 불평불만을 포함한 오늘의 스칼라 끝 [3:20 AM] linflus: 앞으로는 내용 정리보다는 코드를 적극적으로 짜보는 게 이해에 더 도움이 될 것 같다는 생각이 들어서 [3:20 AM] linflus: 이 채널에 내용이 많이 올라오지는 않을 것 같다는 생각도 듬 [3:20 AM] lyuha: 그건 좀 아쉽네요... [3:20 AM] smksyj: 모두 새 인스턴스를 반환하면 [3:20 AM] smksyj: 생성 비용이 너무 크지 않나? [3:21 AM] linflus: 상황따라 그럴 수도 있을듯? [3:21 AM] smksyj: functional하게 짜서 그런가 [3:21 AM] smksyj: 원래는 상태도 가지고 그럴텐데 [3:21 AM] lyuha: 애초에 class가 immutable 이여야 하는 이유가 있는걸까요...? [3:21 AM] smksyj: 내가 봤던 걸로는 [3:21 AM] linflus: functional programming이라서... [3:21 AM] smksyj: 굳이 저렇게 immutable하게 만들지는 않았음 [3:21 AM] smksyj: functional이라서가 맞는 것 같네 [3:21 AM] linflus: 강의가 functional programming 강의.. [3:21 AM] smksyj: ㅇㅇ [3:21 AM] linflus: 자바에 껴넣을 수 있으니 [3:21 AM] linflus: 당연히 스칼라 자체는 상태를 가질 수 있음 [3:22 AM] smksyj: 다만 clojure의 경우 [3:22 AM] linflus: 아니면 짜졌겠지 [3:22 AM] smksyj: 복사 시에 겹치는 상태는 공유하는 방식을 이용하였지만 [3:22 AM] smksyj: scala는 아니겠지... [3:22 AM] linflus: 짜졌겠지 == 웹개발에서 스칼라 못쓸듯 [3:22 AM] linflus: 오 그런 깊은 이야기까지는 모르겠다.. 그건 더 알아봐야 할 부분 [3:22 AM] linflus: 근데 이 강의는 사실 핵심이 스칼라가 아니라 [3:22 AM] linflus: 스칼라로 배우는 함수형 프로그래밍이라 [3:22 AM] smksyj: 함수형 [3:23 AM] linflus: 나오는 개념이 줄창 함수형 프로그래밍 ㅋㅋ [3:23 AM] linflus: 개인적으론 그래서 지금까지는 질리지 않고 매일 볼 수 있는 것 같음 [3:23 AM] linflus: 스칼라로 웹개발 해보아요 였으면 진작 gg치고 채널 먹튀했을듯; [3:23 AM] smksyj: 꽤 아쉽네 [3:23 AM] smksyj: 개인적으로 스칼라가 자랑할 만한 건 [3:23 AM] smksyj: 함수형도 있지만 [3:24 AM] smksyj: 액터 모델이나 [3:24 AM] smksyj: trait이나 [3:24 AM] smksyj: 같은 것들이라고 생각하는데 [3:24 AM] linflus: 그런건 functional한 부분을 먼저 훑고 나서 봐도 될 것 같음 [3:24 AM] linflus: ㅋㅋ [3:24 AM] smksyj: 그것도 강의 있음? [3:24 AM] linflus: 아니 [3:24 AM] linflus: 찾아보면 되지 [3:24 AM] lyuha: 뭔가 [3:24 AM] lyuha: 따라가기 힘들어졌다 [3:24 AM] lyuha: 액테 모델 trait? [3:24 AM] smksyj: Actor라고 해서 [3:24 AM] lyuha: 엑터 모델 ... trait?.. [3:25 AM] smksyj: 스레드를 조금 더 쓰기 편하게? [3:25 AM] linflus: 강의 수준의 샘플 진도 따라잡으면 [3:25 AM] smksyj: 그런 게 있음 [3:25 AM] linflus: 단타 example말고 토이 프로그램을 하나 짤건데 [3:25 AM] linflus: 그럴때 어쩔 수 없이 찾아보게 되겠지 [3:25 AM] smksyj: Actor 모델은 Erlang에서 가져왔다고 하는 것 같던데 [3:25 AM] smksyj: trait은 [3:25 AM] smksyj: 구현을 가지고 있는 Interface [3:26 AM] linflus: ?! [3:26 AM] linflus: abstract class랑 차이점이 뭐지 [3:26 AM] smksyj: 그건 [3:26 AM] smksyj: trait의 구현 부분은 [3:26 AM] smksyj: 특정 클래스의 세부사항이 안 드러나게? [3:26 AM] smksyj: 만들어질걸 [3:27 AM] smksyj: 그래서 인터페이스처럼 어디에든 끼워 넣을 수 있음 [3:27 AM] smksyj: 다만 인터페이스처럼 [3:27 AM] linflus: trait의 instance가 생성 가능하다는건가? [3:27 AM] smksyj: 그걸 구현하는 애들은 몇몇 메소드를 구현해야 함 [3:27 AM] smksyj: 그건 아니고 [3:27 AM] smksyj: trait에 메소드가 여러 개가 있으면 [3:27 AM] smksyj: 그 중 일부는 trait 내부의 메소드를 이용해서 구현되어 있다고 해야 하나 [3:28 AM] smksyj: 대신 몇몇은 trait을 extend 하는 클래스가 override를 해 줘야 함 [3:28 AM] smksyj: 그래서 몇 개만 override를 해 주면 [3:29 AM] smksyj: 나머지 메소드들은 trait 안에서 이미 trait 자체의 메소드를 이용해서 정의가 되어 있기 때문에 [3:29 AM] smksyj: 전부 다 override 안 해도 된다는 얘기 [3:29 AM] smksyj: ```trait Similarity { def isSimilar(x: Any): Boolean def isNotSimilar(x: Any): Boolean = !isSimilar(x) } ``` [3:29 AM] smksyj: 여기서 isNotSimilar 같은 경우는 [3:29 AM] smksyj: isSimilar를 이용해서 구현이 되어 있고 [3:30 AM] smksyj: ```class ExampleClass extends Similarity { } ``` [3:30 AM] smksyj: 이런 애가 있으면 [3:30 AM] smksyj: 얘는 isSimilar만 override 해 주면 [3:30 AM] linflus: ?! 들을수록 abstract class랑 차이를 잘 모르겠어 [3:30 AM] linflus: abstract class도 일부 메소드는 정의가 되어있고 [3:30 AM] smksyj: 음... [3:30 AM] linflus: 하지만 모든 메소드가 정의되어있는 건 아니라서 instance는 못만들고 [3:30 AM] smksyj: 생각해보니 그런 것 같네... [3:30 AM] linflus: 상속받는 class에서 정의해야하는 거 아님? [3:30 AM] linflus: 내가 기억 잘못하는걸지도 [3:30 AM] linflus: abstract class를 시험지에 적어내던 것이 언제적일인가 싶긴 함 [3:31 AM] smksyj: 아 근데 [3:31 AM] smksyj: abstract class는 [3:31 AM] smksyj: 복수 상속이 안 되잖아 [3:31 AM] linflus: 아 [3:31 AM] linflus: 그렇군 [3:31 AM] linflus: 그건 중대한 차이군 [3:31 AM] linflus: !! [3:31 AM] linflus: 다중상속이 된다면 그건 차이가 있네 ㅋㅋ [3:32 AM] linflus: 크 오늘은 일찍 자려고 일찍 보기 시작했는데 [3:32 AM] linflus: 예제파티하다보니 결국 자는 시간은 똑같아 [3:32 AM] smksyj: 많이 봐서 늦게 자는군 [3:32 AM] linflus: ㅋㅋㅋㅋ [3:32 AM] linflus: 대신 이미 나온 영상 진도 더 빨리 따라잡고 다른걸 할 수 있겠지 [3:32 AM] linflus: 자러가야겠다.. [3:32 AM] linflus: 학부생들도 좋은밤되세요.... [3:33 AM] lyuha: 안녕히 주무세요 [3:33 AM] smksyj: ㅂㅂ [3:33 AM] smksyj: 진짜 ZP의 귀감이군... [3:33 AM] lyuha: .....그러게요 [3:33 AM] linflus: 그럴리가 [3:34 AM] lyuha: 3:33분에 [3:34 AM] lyuha: 야식 끝. [3:39 AM] smksyj: @lyuha: http://www.scala-lang.org/old/node/242 [3:39 AM] smksyj: http://savanne.be/articles/concurrency-in-erlang-scala/ [3:39 AM] smksyj: 스레드의 대안으로 actor 모델이라는 것을 사용하였음 [3:39 AM] smksyj: 확실히 멀티코어 환경이 보편화 되면서 [3:39 AM] smksyj: 보다 안정적인 스레드의 사용은 [3:39 AM] smksyj: 많이들 고려를 하나보지 [3:40 AM] smksyj: clojure의 STM도 스레드의 대안으로 만들어진 물건임 [10:58 AM] skylibrary: joined #scala ----- Today May 28th, 2014 ----- [2:45 AM] linflus: 오늘의 스칼라도 예제파티... [2:45 AM] linflus: 하지만 오늘은 버그노예질을 하고 집에 택시타고 들어왔기때문에 영상 하나만 봤다 [2:46 AM] linflus: 솔직히 말해서 Java개발을 해본 사람에게 크게 새로운 내용은 없었음 [2:46 AM] linflus: 그래서 특별히 언급하고 싶은 건 require와 assert [2:48 AM] linflus: 음 둘 다 testing에 사용할 수 있는 function [2:49 AM] linflus: 사실 강의 영상은 스칼라 아저씨가 설명하고 싶은 부분을 설명하기때문에 그 이후에 다시 검색해야하는 부분이 생긴다 [2:50 AM] linflus: 이를테면 강의 영상을 보면 require와 assert의 차이를 조건을 만족시키지 못했을 때 require는 IllegalArgumentException을 발생시키고 (edited) [2:50 AM] linflus: assert는 AssertionError를 발생시킨다는 것 [2:52 AM] linflus: 그래서 require는 function을 call할때의 전제조건을 강제하는 데 쓰이고(강의에서는 분수의 분모는 0이 될 수 없다는 전제로 예를 듬) [2:52 AM] linflus: assert는 function 자체에 대한 테스트에 쓴다 [2:52 AM] linflus: 정도로 이해하게 되는데 이게 맞나 싶은 생각이 듬 [2:53 AM] linflus: 아 그리고 또 하나는 constructor 문법 (edited) [2:55 AM] linflus: class Complex(a:Int, b:Int) 에서 a, b 두 인자를 받는 constructor 외에 인자를 아예 받지 않거나 하나만 받는 다른 contructor를 정의하고 싶다면 class 내에 [2:55 AM] linflus: def this(a:Int) = Complex(a, 0) [2:56 AM] linflus: 이런식으로 this라는 키워드를 사용해 정의해줄 수 있다 [2:56 AM] linflus: Intellij 문제는 아직 해결법을 몰라서 내일 좀 더 손을 대거나 그냥 이클립스를 다시 깔 생각 [2:56 AM] linflus: 사실 오늘부터 코드짜는데 시간을 좀 더 들이려고 노트북을 들고나갔는데 10시까지 버그노예하는 바람에... [2:57 AM] linflus: 내일은 야근만 안 하게 된다면 좀 더 구색을 갖춘 예제를 가져올 수 있기를 바라며 오늘의 스칼라는 끝 (edited) [2:57 AM] smksyj: 기억이 맞다면 [2:57 AM] smksyj: scala는 생성자가 복수 개 있으면 [2:58 AM] smksyj: 기본 생성자가 아닌 것들은 [2:58 AM] smksyj: 반드시 내부에서 기본 생성자를 호출하게? 그런 제약이 있었던 걸로 기억하는데 [2:58 AM] linflus: 아하 진짜? [2:58 AM] smksyj: 그런 얘기는 혹시 뭐 없었나요 [2:58 AM] smksyj: 당시에 보면서 [2:58 AM] smksyj: 뭐 저렇게 불편하게 만들었지 [2:58 AM] smksyj: 하는 생각을 했던 것 같은데 [2:58 AM] linflus: 영상 예제에서 기본 생성자를 호출하긴 했지만 딱히 그런 말 들은 기억이 없는데 영어니까 놓쳤을 수 있음 [2:58 AM] linflus: 다시 그 부분 봐야지 [3:00 AM] linflus: 일단 다시 봤을때 기본 생성자는 class body에 있는 statement를 모두 실행한다는 말도 있군 [3:00 AM] smksyj: ```class Employee(val firstName:String, val lastName:String){ var age:Int = 0 var city:String = _ def this(firstName:String, lastName: String, city:String, age:Int){ this(firstName, lastName, city) this.age = age } def this(firstName:String, lastName: String, city:String){ this(firstName,lastName) this.city = city } } ``` [3:00 AM] smksyj: def this(firstName:String, lastName: String, city:String){ this(firstName,lastName) this.city = city } [3:01 AM] smksyj: 아마 Employee(val firstName:String, val lastName:String) [3:01 AM] smksyj: 이게 디폴트 생성자지 싶은데 [3:01 AM] smksyj: ```def this(firstName:String, lastName: String, city:String){ this(firstName,lastName) this.city = city } ``` [3:01 AM] smksyj: 저 안에서 this(firstName, lastName)의 호출이 [3:01 AM] smksyj: 의무였던 걸로 기억함 [3:03 AM] linflus: 아; 다시 봐도 그런 말은 없네 [3:03 AM] smksyj: 그런가 [3:03 AM] linflus: 그게 틀렸다기보다 그 얘기를 별로 그 타이밍에 하고싶지 않았던것같기도 [3:03 AM] smksyj: ㅇㅇ [3:03 AM] linflus: 별로 흐름이랑 상관없어서.. [3:03 AM] smksyj: 근데 나도 정확하게 기억은 안 나서 [3:03 AM] smksyj: 생성자 얘기 하길래 [3:04 AM] smksyj: 혹시 그런 얘기가 있었나 궁금해서 그럼 [3:04 AM] linflus: ㅇㅇ 나도 궁금해져서 검색중 [3:05 AM] smksyj: Auxiliary Constructor [3:06 AM] linflus: http://codemonkeyism.com/top-5-things-to-know-about-constructors-in-scala/ [3:06 AM] linflus: Secondary constructors like this() need to delegate to another constructor to work (Thanks @Synesso). [3:06 AM] smksyj: Secondary constructors like this() need to delegate to another constructor to work [3:06 AM] linflus: 이 말은 반드시 그 호출하는게 기본생성자여야 하는건지 [3:06 AM] linflus: 그런 느낌은 아닌데 [3:06 AM] smksyj: 굳이 기본생성자는 아니어도 됨 [3:06 AM] linflus: ㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋㅋ [3:06 AM] smksyj: 근데 [3:06 AM] linflus: 같은문장 [3:07 AM] smksyj: 걔가 호출한 다른 Auxiliary Constructor가 (edited) [3:07 AM] smksyj: 타고타고 가면 [3:07 AM] smksyj: 반드시 기본 생성자를 호출해야 할 걸 [3:07 AM] linflus: 결국 class body의 모든 문장을 언젠가 실행해야한다 [3:07 AM] linflus: 그런 맥락에서? [3:08 AM] smksyj: Auxiliary constructors can contain more than a single invocation of another constructor, but their first statement must be said invocation. [3:08 AM] linflus: 그런거면 이해가 감.. 하지만 모든 constructor가 반드시 직빵으로 primary constructor를 호출해야한다면 비효율적이란 느낌도 들고.. [3:09 AM] smksyj: 생성 시에 디폴트 생성자에 있는 변수는 초기화가 되어야 하지 싶음 [3:09 AM] linflus: 아 이 부분은 사실 좀 더 찾아보고 싶긴 하다 문법적인 면에서라기 보다는 [3:10 AM] linflus: 스칼라에서 생성자 호출할때에 대해서 좀 더 찾아봐야겠다는 생각이 듬 [3:10 AM] smksyj: 내가 이거에 관심 있는 이유는 [3:10 AM] smksyj: 이거 엄청 불편할 것 같은데 [3:10 AM] smksyj: 정말 이렇게 한 거 맞나 궁금해서 -_-;; [3:10 AM] linflus: 이 부분은 영상과 별도로 내일 찾아보고 추가적으로 써야겠음 ㅋㅋ [3:10 AM] linflus: 채널을 활용하길 잘했네.. 혼자 위키에 몇줄 대충 쓰는것보다 [3:11 AM] smksyj: http://stackoverflow.com/questions/10426146/constructors-in-scala-primary-auxiliary-default-primary constructors in scala (primary/auxiliary/default primary) A quite simple exercise from Cay Horstmann's book « Scala for the impatient » keeps puzzling me. It's about primary,auxiliary and default primary constructors : ex 5.10 : Consider the class [3:11 AM] linflus: 쓰기도 편하고 공부하기에도 더 좋아 [3:11 AM] smksyj: every constructor invocation in Scala will end up eventually calling the primary constructor of the class. [3:11 AM] linflus: 그렇군 [3:11 AM] linflus: 복잡하게 짜려다가 폭망 [3:11 AM] linflus: 할 수 있다 [3:11 AM] linflus: 뭐 그런 생각들이 머리를 스침 [3:12 AM] linflus: 아 난 이렇게 짜고싶은데 왜 안 돼!! 같은 그림이.. [3:12 AM] smksyj: 오늘도 3시는 넘는군 [3:12 AM] linflus: 어쩔 수 없음 10시까지 야근해서 [3:12 AM] smksyj: 슬슬 원준이가 나올 것 같은 분위기인데 [3:12 AM] smksyj: 오늘은 안 나오네 [3:12 AM] linflus: ㅋㅋㅋㅋㅋ [3:12 AM] linflus: 난 자러가야지.. [3:12 AM] smksyj: 오늘도 고생하셨습니다 [3:12 AM] smksyj: ㄳㄳ [3:12 AM] linflus: 좋은 피드백 ㄳㄳ [3:14 AM] smksyj: 음... primary constructor의 val 변수의 초기화 때문에 [3:14 AM] smksyj: 저런 정책을 취했나보네 [3:15 AM] smksyj: val은 반드시 초기값이 들어있어야 하니까 [3:16 AM] syjsmk: joined #scala from an invitation by @smksyj [3:45 AM] lyuha: 음...나오기 어려운 [3:45 AM] lyuha: 주제였습니다? [10:37 AM] syjsmk: 헉 잠 안자는 사람들의 채널인가요 [10:49 AM] lyuha: 보통 다들 늦게 자죠... [2:43 PM] jereneal: joined #scala [3:07 PM] flyjsw: joined #scala