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
  • 2 함수 식 프로 그래 밍 이 가 져 온 효과
  • 2.1 음반 데이터베이스 - 의 예
  • 2.2 어떻게 조회 합 니까?
  • 2.3 대응 js 실현
  • 2.3.1 배열 을 데이터베이스 로 한다.
  • 2.3.2 조회 조작
  • 2.3.3 조회 함수 생 성기


  • 3 총화

  • 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

    좋은 웹페이지 즐겨찾기