스터디가 꿀잼이었다.
다른 분들이 안오셔서 종명님과 짝프로그래밍으로 문제풀이를 시작했는데,
힘들어서 그만하려고 보니 시간이 5시간이나 훌쩍 지나있었다.
짝프로그래밍을 하면 혼자할때보다 피드백이 훨씬 촘촘해진다.
혼자할때가 Plan Do Check Action 이라면,
짝프로그래밍 할때는 Plan Check Do Check Action Check 같은 느낌이다.
주말이라서 즐겁게 코딩하려고 마음을 먹었다.
즐거워지기 위해 스스로에게 선택의 자유를 주었다.
우선순위에 신경쓰는걸 잠시 멈추고 배우고 싶은 순서대로 배웠다.
Deno 를 체험해보았다.
생각보다 빨리되어서 진작에 해볼걸 이라는 생각이 들었다.
가볍게 현재 알고리즘 풀때 하는 세팅을 적용해보았다.
일단은 노드모듈이 없어져서 프로젝트자체가 가벼워져서 좋았다.
import / export 구문 사용도 가능해졌다.
기본적인 테스팅은 자체지원을 하는데, 뭔가 jest 스타일로 하고 싶어서
라이브러리를 사용했다.
인수들이 모두 평가된 후에야 연산을 시작하는 함수를 엄격한 함수,
그렇지 않은 함수를 엄격하지 않은 함수라고 한다.
다음 코드는 자바스크립트에서 reduce 와 비슷한 역할을 하는데,
배열을 오른쪽부터 하나씩 접는 역할을 한다.
def foldRight[A](list: List[A], z: A)(f: (A, B) => B): B =
list match {
case Nil => z
case Cons(h, t) => f(h, foldRight(t, z)(f))
}
이 때, 만약 f 가 엄격한 함수라면,
h 와 foldRight 이 모두 평가된 이후에야 계산을 시작한다.
하지만 foldRight 은 재귀함수이기 때문에, 모든 재귀가 쌓인 후에야 연산을 시작하게 된다!
따라서, 분명히 중간에 결과가 나올 것이 자명한 경우(예를들면 0 이 리스트에 있고, 곱하기 연산)에도
재귀를 모두 돌게 되어서 비효율적이다.
종명님과 같이 궁리를 하다가 다음과 같이 f 를 엄격하지 않은 함수로 변경하고,
하나가 0 일때는 바로 0을 뱉게 해주었더니 재귀를 모두 돌지 않았다.
f: (A, => B) => B): B
// foldRight 에 넣어줄 함수
def lazyProductOf(a: Int, b: => Int) = {
if (a == 0) 0
else a * b
}
저녁에는 자바에서 스트림을 살펴보았는데, 스트림에서도 연산을 필요한때까지 지연시킨다는 아이디어가 활용되었다.
다음은 무한 스트림에서 0 부터 2 까지의 리스트를 반환하는 코드다.
List<Integer> list = Stream.iterate(0, x -> x + 1)
.limit(3)
.collect(Collectors.toList())
이때 무한스트림이란게 존재할 수 있는 이유는, 마지막에 결과연산이 적용되기 전까지는,
실제 계산을 하지 않아서 그렇다.
즉, 결과연산이 적용되기 전까지는 단지 계산은 서술되어 있을 뿐이다.
스칼라 책에서는 요런 비슷한 상황에 대해서 서술 시점과 평가 시점을 분리했다고 나와있다.