js 인 코딩 에 대한 시사 점
23081 단어 lisp
<!--
/*--><![CDATA[/*><!--*/
html { font-family: Times, serif; font-size: 12pt; }
.title { text-align: center; }
.todo { color: red; }
.done { color: green; }
.tag { background-color: #add8e6; font-weight:normal }
.target { }
.timestamp { color: #bebebe; }
.timestamp-kwd { color: #5f9ea0; }
p.verse { margin-left: 3% }
pre {
border: 1pt solid #AEBDCC;
background-color: #F3F5F7;
padding: 5pt;
font-family: courier, monospace;
font-size: 90%;
overflow:auto;
}
table { border-collapse: collapse; }
td, th { vertical-align: top; }
dt { font-weight: bold; }
div.figure { padding: 0.5em; }
div.figure p { text-align: center; }
.linenr { font-size:smaller }
.code-highlighted {background-color:#ffff00;}
.org-info-js_info-navigation { border-style:none; }
#org-info-js_console-label { font-size:10px; font-weight:bold;
white-space:nowrap; }
.org-info-js_search-highlight {background-color:#ffff00; color:#000000;
font-weight:bold; }
-->
// <![CDATA[
/*--><![CDATA[/*><!--*/
function CodeHighlightOn(elem, id)
{
var target = document.getElementById(id);
if(null != target) {
elem.cacheClassElem = elem.className;
elem.cacheClassTarget = target.className;
target.className = "code-highlighted";
elem.className = "code-highlighted";
}
}
function CodeHighlightOff(elem, id)
{
var target = document.getElementById(id);
if(elem.cacheClassElem)
elem.className = elem.cacheClassElem;
if(elem.cacheClassTarget)
target.className = elem.cacheClassTarget;
}
/*]]>*/
// ]]>
js 인 코딩 에 대한 시사 점
Table of Contents
1 lisp 와 javascript
javascript 은 lisp 외 투 를 걸 친 C 이기 때문에 눈 lisp 를 보 러 갔 습 니 다. 전 춘 이 번역 한 '실 용 common - lisp 프로 그래 밍' 자 바스 크 립 트 는 함수 호출 시 문맥 this 를 지정 할 수 있 습 니 다. common - lisp 의 funcall 과 funapply 를 보 았 을 때 이름 만 봐 도 유 난 히 친절 합 니 다.
2 함수 식 프로 그래 밍 이 가 져 온 효과
프로 그래 밍 개념 이나 방법론 이 문 제 를 더 잘 해결 하고 있다 면 그것 은 좋 은 것 입 니 다. 여기 서 lisp 가 쓴 데이터 조회 함 수 를 보고 저 는 충격 을 받 았 습 니 다.
2.1 음반 데이터베이스 - 의 예
메모리 에 저 장 된 음반 데이터베이스 * db *
(defvar *db* nil) ;; lisp
;; cd
(defun makcd (title artist rating ripped)
(list :title title :artist artist :rating rating :ripped ripped))
;;
(defun add-record(cd)
(push cd *db*))
(add-record (make-cd "Roses" "Kathy Mattea" 7 t))
(add-record (make-cd "Fly" "Dixie Chicks" 8 t))
;; *db*
((:TITLE "Roses" :ARTIEST "Kathy Mattea" 7 t)
(:TITLE "Fly" :ARTIEST "Dixie Chicks" 8 t))
많은 데 이 터 를 추가 한 후...
2.2 어떻게 조회 합 니까?
함수 하나 보고.
(remove-if-not #'evenp '(1 2 3 4 5 6 7 8 9 10))
;; -> (2 4 6 8 10)
함수 evenp 는 필터 함수 입 니 다. 매개 변수 가 짝수 일 때 진실 을 되 돌려 줍 니 다. 익명 함수 로 필터 로 쓸 수도 있 습 니 다.
(remove-if-not #(lambda (x) (= 0 (mod x 2))) '(1 2 3 4 5 6 7 8 9 10))
;; -> (2 4 6 8 10)
js 와 그 대비 함수 는
[1,2,3,4,5,6,7,8,9].filter(function(n){
return n%2 == 0 ;
})
remove - if - not 와 같은 필터 함수 가 있 습 니 다. 위 에 있 는 데이터 조회 로 돌아 갑 니 다. 사실은 필 터 를 추가 하 는 것 입 니 다. 예 를 들 어 * db * 에서 artist 가 'Dixie Chicks' 라 는 데이터, lisp 스타일 의 코드, 위의 짝수 필터 함수 와 유사 합 니 다. lambda 익명 함수 에 봉 인 됩 니 다.
(defun select-by-artist (artist)
(remove-if-not
#'(lambda (cd) (equal (getf cd :artist) artist)) *db*))
지금 바로 호출 할 수 있 습 니 다.
(select-by-artist "Dixie Chicks")
"Dixie Chicks" 라 는 아 티 스 트 를 가 져 옵 니 다.데이터 입 니 다. 주의해 야 할 것 은 위의 함 수 는 artist 키워드 만 조회 할 수 있 습 니 다. 예 를 들 어 평 점 rating 이 7 인 다른 키 워드 를 조회 하려 면 select - by - artist 와 유사 한 함수, select - by - itle select - by - rating 등 을 써 야 합 니 다. 따라서 통용 되 는 함 수 를 써 서 하나의 함 수 를 매개 변수 로 받 아들 일 수 있 습 니 다.
(defun select (selector-fn)
(remove-if-not slector-fn *db*))
select - by - artist 함수 의 익명 함 수 를 추출 할 수 있 습 니 다.
(defun artist-selector (artist)
#'(lambda (cd) (equal (getf cd :artist) artist)))
그러면 이런 형식의 호출.
(select-by-artist "Dixie Chicks")
되다
(select (artist-selector "Dixie Chicks"))
유사 한 것 은 title - selector 를 쓸 수 있 습 니 다.
(defun title-selector (title)
#'(lambda (cd) (equal (getf cd :title) title)))
타이틀 조회 가능 합 니 다.
(select (title-selector "Fly"))
그러나 조회 할 필드 가 많다 면 xxx - selector 를 바보 같이 많이 써 야 하 는 것 이 아 닙 니까? 함수, 동적 생 성 함 수 를 쓸 수 있 습 니까? 들 어 오 는 매개 변수 에 따라 해당 하 는 매개 변수 여과 함 수 를 생 성 합 니 다. 예 를 들 어 title 에 들 어가 면 title - selector 를 생 성 합 니 다. 아 티 스 트 에 들 어가 면 아 티 스 트 - selector 를 생 성 합 니 다. 둘 다 들 어 오 면 하나의 and 관계 lisp 입 니 다.샘플 코드 는 매우 자 연 스 럽 습 니 다. 어 지 러 워 보이 지만 ~ 이런 함수 가 있 으 면 조회 조작 이 이렇게 보 입 니 다.
(select (where :title "Fly" :artist "Dixie Chicks"))
where 는 바로 실현 해 야 할 함수 입 니 다. SQL 문 구 를 알 고 있다 면 왜 where 라 고 부 르 는 지 알 수 있 을 것 입 니 다.
(defun where (&key title artist rating)
#'(lambda (cd)
(and
(if title (equal (getf cd :title) title) t)
(if artist (equal (getf cd :artist) artist) t)
(if rating (equal (getf cd :rating) rating) t))))
문법 디 테 일 에 얽 매 이지 않 고 반복 을 없 애 는 효과 만으로 도 인상적 입 니 다. where 함수 하나 로 많은 xxx - selector 를 해 치 웠 습 니 다.
(select (where :title "Fly"))
... 에 해당 하 다
(select (title-selector "Fly"))
분명히 전 자 는 매우 통용 된다.
2.3 대응 js 실현
함 수 는 첫 번 째 유형 입 니 다. 함 수 는 매개 변수 로 할 수 있 습 니 다. js 도 이러한 특성 을 가 진 js 가 where 와 같은 기능 을 실현 할 때 표 현 력 이 어 떻 습 니까? 저 는 실현 해 보 았 습 니 다.
2.3.1 배열 을 데이터베이스 로 한다.
var db = [];
function makecd(title,artist,rating,ripped){
return {title:title,artist:artist,rating:rating,ripped:ripped};
}
function addRecord(makecd,title,artist,rating,ripped){
db.push(makecd(title,artist,rating,ripped));
}
addRecord(makecd,"Roses","Kathy Mattea",7,true)
addRecord(makecd,"Fly","Dixie Chicks",8,true);
/* db :
[ { title: 'Roses',artist: 'Kathy Mattea',rating: 7,ripped: true },
{ title: 'Fly', artist: 'Dixie Chicks', rating: 8, ripped: true } ]
*/
2.3.2 조회 조작
js 의 filter 함수 와 lisp 의 remove - if - not 대비 두 가지 구현 lisp way:
(defun select-by-artist (artist)
(remove-if-not
#'(lambda (cd) (equal (getf cd :artist) artist)) *db*))
javascript way:
function selectByArtist(artist){
return db.filter(function(cd){
return cd.artist == artist;
});
}
/*
console.log(selectByArtist('Kathy Mattea'));
[ { title: 'Roses', artist: 'Kathy Mattea', rating: 7, ripped: true } ]
*/
많은 판단 을 피하 기 위해 서 는 위 에서 title 을 판단 해 야 한다 면 js 의 실현 은 더 해 야 한다.
function selectByArtist(artist,title){
return db.filter(function(cd){
return cd.artist == artist && cd.title == title;
});
}
하지만 title 은 선택 할 수 있 습 니 다. 진행 & 조작 전에 판단 title 이 들 어 왔 습 니까? 여기 있 습 니 다.
function(cd){
return cd.artist == artist && cd.title == title;
}
... 에 해당 하 다
(defun artist-selector (artist)
#'(lambda (cd) (equal (getf cd :artist) artist)))
lisp 처럼 where 조건 필터 구현
/**
*
* , ,
*/
function all(){
var fns = [].slice.call(arguments),
len = fns.length;
return function(){
var i=0,
fn
while(fn = fns[i]){
i++;
if(!fn.apply(null,arguments)){
return false;
}
}
return true;
};
}
이것 은 도구 함수 입 니 다. 임의의 함 수 를 매개 변수 로 합 쳐 진 함 수 를 되 돌려 줍 니 다. 이 임의의 함수 의 값 만 진실 입 니 다. 이 합 쳐 진 함수 의 값 은 진 함수 로 전달 되 고 함수 의 반환 값 도 함수 아래 의 프 리 젠 테 이 션 입 니 다.
var retfn = all(
function(n){
return n>0;
},
function(n){
return n<10}
);
var ret = [11,-1,5,4,9,11];
ret = ret.filter(retfn);
console.log(ret);
->[ 5, 4, 9 ]
프레젠테이션 의 목적 으로 함께 판단 할 수 있 는 논리
ret.filter(function(n){
return n>0 && n<10;
})
두 함수 로 분해 하 였 다
2.3.3 조회 함수 생 성기
위의 lisp 에서 실 현 된 where 함 수 는 매개 변수 에 따라 (& key title artist rating) 합 쳐 진 조회 함수 (& key title artist rating) 와 같은 이름 이 있 는 매개 변수 목록 을 만 들 수 있 습 니 다. js 에 서 는 대상 {key 1: val 1, key 2: val 2} 으로 시 뮬 레이 션 할 수 있 습 니 다.
/**
*
*/
function makequery(o){
var fns = [];
for(var x in o){
fns.push(function(cd){
return o[x] == cd[x]
});
}
return fns;
}
/*
var allquery = makequery({rating:8});
var allfn = all.apply(null,allquery);
var queryresult = db.filter(allfn);
console.log(queryresult);
*/
예 를 들 어 Makequery ({rating: 8}) 는 함수 하 나 를 되 돌려 줍 니 다. 이 함 수 는 들 어 오 는 대상 의 rating 필드 가 8 일 때 진짜 로 돌아 갑 니 다. 그렇지 않 으 면 두 필드 에 들 어 오 면 두 함 수 를 포함 한 배열 로 돌아 갑 니 다. 도구 함수 all 은 여러 개의 여과 함 수 를 하나 로 합 칠 수 있 습 니 다. 이 경우 js 버 전의 where 함수 도 큰 성 과 를 거 두 었 습 니 다.
/*
*
*/
function where(o){
return db.filter(all.apply(null,makequery(o)));
}
/**
var ret = where({rating:8})
console.log(ret);
*/
select 기능 이 실 현 된 후, 동시에 update 기능 도 실현 합 니 다.
/**
* ,
* update(db,where({artist:'Dixie Chicks'}),{rating:8.5})
*/
function update(db,queryresult,to){
queryresult.forEach(function(item){
var idx = db.indexOf(item);
db.splice(idx,1,merge(item,to));
});
}
function merge(original,extra){
for(var x in extra){
original[x] = extra [x];
}
return original;
}
/*
update(db,where({artist:'Dixie Chicks'}),{rating:8.5});
console.log(db);
*/
function deldb(db,queryresult){
queryresult.forEach(function(item){
var idx = db.indexOf(item);
db.splice(idx,1);
});
}
/*
deldb(db,where({artist:'Dixie Chicks'}));
console.log(db);
*/
3 총화
lisp 를 조금 배 웠 는데 함 수 를 괴 롭 히 고 함수 로 함 수 를 생 성 하 는 것 도 코드 를 다시 사용 하여 번 거 로 움 을 줄 이 는 효과 적 인 방법 입 니 다.
Author: tom
Date: 2012-08-20 23:22:11 CST
HTML generated by org-mode 6.33x in emacs 23
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Emacs Lisp 디버깅 팁미니 버퍼에 "잘못된 유형 인수"또는 이와 유사한 것이 있습니까? 스택 추적을 얻을 수 있습니까? 이상한 "잘못된 유형 인수"오류 또는 이전에 미니버퍼에 인쇄된 유사한 오류 중 하나를 받았을 것입니다. 대신 스택 추...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.