2018년 8월 17일 금요일

[javascript] 함수를 이용한 개발-01

출처 : 하스켈로 배우는 함수형 프로그래밍

함수를 이용한 개발

- 맞을지 안 맞을지도 모르는 부품을 만들거나 맞추는 능력


이 코드의 내용은 전적으로 "하스켈로 배우는 함수형 프로그래밍"의 내용을 가져온 것이다. 그곳에서 내가 더한 내용은 소스 맨밑에 currying을 이용한 부분밖에 없다.
해당 내용은 서적을 읽어야 왜 이러한 기술이 중요한 지 알 수 있다.
서적에서는 C언어로는
  1. 실행시간에 함수를 생성할 수 없어서 결국 for-loop만을 고집해야 하는 점.
  2. 그 작은 차이가 조금씩 코드를 변화하고
  3. 결국 개발자의 생각하는 방식마저 변화시킬 것이며
  4. 자유를 얻게 될 것이라고 말하는 것 같았다.
해당 소스는 꽤나 단순하다.(??) 그리고 내용을 이해하지 않고 함수들의 구조들이 어떻게 변화되는지만 봐도 흥미롭다.
좌표에 한 점이 있는데 이 점을 dx,dy로 이동시키느냐, 혹은 각도(theta)를 이용해서 회전함으로 좌표를 옮기느냐 하는 것이다. (혹은 둘다)
// 객체 복사용
function clone(obj) {
  var f = function(){};
  f.prototype = obj;
  return new f;
}

// 병행 이동의 프리미티브
var trans = function (dx, dy, coord) {
 var result = clone(coord);
 result.x += dx;
 result.y += dy;
 return result;
}

var rotate = function (theta, coord) {
 var result = clone(coord);
 result.x = Math.cos(theta) * coord.x - Math.sin(theta) * coord.y;
 result.y = Math.sin(theta) * coord.x + Math.cos(theta) * coord.y;
 return result;
}

// 설정을 베이스로 한 병행 이동
var transByConfig = function (config, coord) {
 return trans(config.ofsX, config.ofsY, coord);
}

// 설정을 베이스로 한 회전
var rotateByConfig = function (config,coord) {
 var preTrans = trans(-config.rotAt.x, -config.rotAt.y, coord);
 var rotated = rotate(config.theta, preTrans);
 var postTrans = trans(config.rotAt.x, config.rotAt.y, rotated);
 return postTrans;
}

// 설정을 베이스로 한 좌표 변환
var convertByConfig = function(config, coord) {
 return transByConfig(config, rotateByConfig(config, coord));
}
var config = {
 rotAt : { x : 0.5, y : 0.5 }
 , theta : Math.PI / 4
 , ofsX : -0.5
 , ofsY : -0.5
}

var unit_rect = [
{x:0,y:0}, {x:0,y:1}, {x:1,y:1}, {x:1,y:0}
]

// 여기서 coord가 map으로 연결되서서 계속바뀌고
// config는 그대로 계속 공통으로 쓰게 되는 함수를 콜해서 리턴하는 익명함수를 각각 만들어서 실행한다.
var converted_rect = unit_rect.map(function(coord) { 
 return convertByConfig(config, coord);
});

converted_rect.map(function(coord) {
 console.log('(' + coord.x.toFixed(6) + ',' + coord.y.toFixed(6)+')');
});

/// curry를 사용하면 좀 더 이뻐 보일 수 있겠다.
console.log('====');
var curriedConvertedByConfig = function(coord) {
 return convertByConfig(config, coord);
}
var converted_rect2 = unit_rect.map(curriedConvertedByConfig);
converted_rect2.map(function(coord) {
 console.log('(' + coord.x.toFixed(6) + ',' + coord.y.toFixed(6)+')');
});
위 내용을 html을 하나 생성해서 로드해보자.

다음페이지
http://www.whynam.com/2018/08/javascript-02.html

댓글 없음 :

댓글 쓰기