compare between sparse array and dense one in JavaScript

 

According to the section 15.4 of ECMA-262 specification, the array is called sparse when it has one or more of hole.

Because an array is simply a map from indices to values, they can have a hole.

In case that array has a hole, you can figure it out that hole is just skipped by getOwnProperty() or forEach():

1
2
3
>> var a = [2, , , 3];
>> Object.getOwnPropertyNames(a);
["0", "3", "length"]

 

undefined is a type itself in JavaScript and there is a global variable named undefined. You can find it to check:

1
2
>> typeof undefined;
"undefined"

 

Undefined means that a variable has been declared but not yet been assigned a value. Therefore, the latter is not sparse array.

1
2
3
>> var b = [2, undefined, undefined, 3];
>> Object.getOwnPropertyNames(b);
["0", "1", "2", "3", "length"];

 

Regarding the example in the presentation 1, the two of array are not equal nor identifical. So, the result of expression is false (by section 11.9.4, ECMA-262);

1
2
>> [2, , , 3] == [2, undefined, undefined, 3];
false

 

  1. http://www.slideshare.net/ukjinplant/ss-36334184 , page 15  

Boogie Board 9.7 Sync 한달 사용기

boogieboard-9.7-sync
끄적거린 노트를  PDF 혹은 JPG 포맷으로 저장할 수 있는 신형 Boogie Board 모델이다. Bluetooth로 PC(혹은 맥)와 태블릿, 핸드폰간에 동기화 시킬 수 있고 펜으로 그리는 동안 화면에도 동일하게 표시되는 Live Drawing 기능도 지원한다.

 

제품이 출시되자마자 눈독들여왔으나 한국내 정식수입이 되지않아 마우스 위에서 손가락만 떨고있던 차에  WWDC 2014 행사에서 돌아오는 지인의 도움을 받아 손에 쥐었다.

 

한달정도 사용해보니 계획했던 목적에는 크게 지장없지만 몇몇 실망스런 점 때문에 구입을 권할 수준은 아닌듯하다.

 

배터리 지속 시간은 꽤~ 만족스럽다.

쓰지 않으면 꺼버리는 사용패턴 때문인지 배터리 걱정은 잊어먹어도 좋을 만큼 오래간다.  이 글을 쓰는 시점에서 마지막 충전이 언제인지 까물거릴 정도인데 배운 것을 확인할 때마다 적는 습관을 따라 최소 하루에 20페이지 정도 사용하는 빈도임을 감안하자.  매뉴얼에 표준 사용시간은 10일 정도라고 했지만 동기화 할 때만 블루투스를 켠다면 거의 한달이상 사용할 수 있지 않을까 추측한다.

충전 단자도 표준  Micro USB 타입이라 케이블 분실 걱정도 덜어준다.

 

기존 부기보드 필기감보다 못하다

사각거리던 느낌은 온데간데 없고 뭔가 플라스틱판 위로 미끄러지는 느낌이다.  선 굵기는 기존의 절반으로 줄어들어 0.7 샤프나 굵은 볼펜으로 쓴 듯해 좀 더 필기했다는 느낌을 주긴하지만 기존 부기보드의 느낌을 아는 사용자라면 만족스럽지 않을듯.

힘줘서 스타일러스를 눌렀을 때 퍼지는 정도 역시 기존 부기보드에 비해 절반정도 줄어든 듯 보인다. 덕분에 선 사이 사이에  뭉개짐이 적어 전체적으로 깨끗한 이미지를 얻을 수 있다.

 

스타일러스 고장났다

펌웨어 업그레이드 직후 Live Drawing 하는 동안 펜 끝이 보드에 닿지도 않았는데 멋대로 선이 그려지는 문제가 보이기 시작했다.  보드에는 표시되지 않지만 PDF로 저장된 문서에는 글자를 연결하는 선으로 보여 읽을 수 조차 없었다.  30페이지 가량을 그렇게 망쳐버려 열 제대로 받아 항의 메일을 보냈지만 이틀이 지나도록 답이 없어 페이스북 메세지를 보냈더니 답이 왔다.  기기 불량으로 보이니 바꿔준다고는 하지만 일주일이 지난 지금까지 발송했다거나 처리 상태를 알려주는 메일이 오진 않았다.   기다리다 못해 스타일러스 펜팁을 제거하고 써봤더니 문제없네?;;;  뭐냐;; 이 황당함은..   고객 응대하는 모습이나 제품 상태, 어플리케이션 완성도로 짐작컨데 좀.. 업체가 ..  허접해 보인다.

 

싱크 어플리케이션은 알바줘서 만들었나보다

안드로이드 어플에서는  블루투스 연결이 시원치 못해 어플을 죽이는 경우가 잦고 Live Drawing이 필요할때면 연결이 끊어져있어 기록하는데 방해를 받는 경우가 많았다.  일단 어플이 못생겨 싱크하지 않을 때 메모리를 점유하지 못하도록 즉시 종료해버린다. 덕분에 배터리 아낄 수 있었다고 본다.  맥용 어플은 화장실에서 코딩했는지 맥어플스러움은 도저히 찾을 수 없고 비대터진 UI를 자랑한다.   게다가 Erase 버튼 눌러 삭제했던 페이지까지 일단 보관되므로 실제로 지우기 위해서는 부기보드를 USB 외장 하드로 연결한뒤 폴더내에서 직접 삭제해줘야 한다.  Erase 버튼을 누르면 실제로 삭제하겠냐는 옵션을 제공하기에는 기록된 노트 데이타가 너무 소중하다 여겼나보다. #Wtf

 

생뚱맞은 외형,  베젤때문에 사람들 앞에서 내놓기 .. 좀.. 그르타…

기본 부기보드는 버스에서나 지하철에서도 별 신경쓰지 않고 사용할 수 있었으나 9.7 Sync 모델은 A4 크게에 가까워서 부담스럽다.  여기에 휘어진 측면디자인과 베젤의 두께, 검은색과 주황색 조합이 촌티를 극대화 하고 있어 멋을 찾기보단 기능에 만족해야할듯.  스타일러스를 측면에 수납할 수 있고 스타일러스가 굴러가지 못하므로 분실위험은 적다.

 

그러나 쓸만하다

지인에게 부탁해서 구입할 정도로 쇼핑광이 아니며 구입하기 전에 사용예를 분명히 한 케이스라 내게는 적합하다고 생각한다. 그러나 펌웨어 업그레이드가 몇차례 제공되고 전용 어플도 개과천선한다면 그 때 구입해도 늦지 않을 것 같다.

 

 

* 추가: 결정적으로 선명도가 많이~ 떨어진다. Contrast가 약해 낮은 시각이나 보드에서 거리가 한팔 길이보다 멀어지면 선 윤곽이 거의 보이질 않는다.  사용하는데는 크게 문제가 없으나 다른 사람에게 기록한 것을 보면서 뭔가 논의를 한다든가 보여주는 용도로는 적합하지 않다.

 

 

 

 

 

Promises/A+ Spec

then Promises/A+

 

몇달전에 Promises/A+ 스펙의 학습을 위해 일부분만 번역했던 것을 기록차원에서 올려둔다.  

신속히 훝어보려고 번역한 것이며, 굳이 번역할 필요가 없어 보이는 문장은 그대로 두었다. 

 

http://promises-aplus.github.io/promises-spec/

 

An open standard for sound, interoperable JavaScript promises—by implementers, for implementers.

promise는 비동기 오퍼레이션의 궁극적인 결과를 표현한 것이다.  promise represents the eventual result of an asynchronous operation. The primary way of interacting with a promise is through its then method, which registers callbacks to receive either a promise’s eventual value or the reason why the promise cannot be fulfilled.

이 문서는 then 메소드의 자세한 행동에 대해 기술한다.  This specification details the behavior of the then method, providing an interoperable base which all Promises/A+ conformant promise implementations can be depended on to provide. As such, the specification should be considered very stable. Although the Promises/A+ organization may occasionally revise this specification with minor backward-compatible changes to address newly-discovered corner cases, we will integrate large or backward-incompatible only after careful consideration, discussion, and testing.

기록상으로, Promises/A+은 기존의 Promises/A 제안의 행동적 규정을 분명히 하고 있으며 사실상의 표준 행동 지침으로 확장하고 있고 부족하게 기술했거나 문제가 있는 부분을 생략하고 있다.  Historically, Promises/A+ clarifies the behavioral clauses of the earlier Promises/A proposal, extending it to cover de facto behaviors and omitting parts that are underspecified or problematic.

끝으로 Promises/A+ 스펙의 핵심은 promise에 대해 어떻게 생성하며 만족시키고 거부하는지에 대해서 다루지 않는다. 대신 공통적으로 조작가능한  then 메소드에 대해 촛점을 맞추고 있다. 차후 여러 주제에 대해 언급할 것이다.  Finally, the core Promises/A+ specification does not deal with how to create, fulfill, or reject promises, choosing instead to focus on providing an interoperable then method. Future work in companion specifications may touch on these subjects.

용어

  1. “promise”는 객체이거나 함수이며 Promises/A+ 스펙을 만족하는  then 메소드를 가지고 있다.
  2. “thenable”은  then 메소드를 가진 객체이거나 함수다.
  3. “value”는 적법한 모든 JavaScript 값을 말하며  undefinedthenable 혹은 promise를 포함한다.
  4. “exception”는  throw statement 를 통해 던져진(thrown) 값이다.
  5. “reason”은 promise가 기각된 이유를 나타내는 값이다.

Requirements

Promise 상태

하나의 promise는 다음중 반드시 하나의 상태에 있어야 한다: pending, fulfilled, or rejected.

  1. pending 일때, a promise:
    1. fulfilled 상태나 rejected 상태로 전이할 수 있다.
  2. fulfilled 일때, a promise:
    1. 다른 상태로 전이되서는 안된다.
    2. 반드시 변경되지 않는 값을 가지고 있어야 한다.
  3.  rejected 일때, a promise:
    1. 다른 상태로 전이되서는 안된다.
    2. 반드시 변경되지 않는 값(이유)을 가져야 한다.

여기서, “변경되지 않는 값”이란 immutable identity를 의미하지만 (i.e. ===), deep immutability를 암시하는 것은 아니다.

then method

promise는 반드시 then 메소드를 가져 현재의 값이나 결과값 혹은 이유를 제공할 수 있어야 한다.

promise의 then 메소드는 두개의 인자를 받아들인다:

promise.then(onFulfilled, onRejected)

  1.  onFulfilled 와 onRejected 는 둘다 생략가능한 인자다:

    1.  만약 onFulfilled이 함수가 아니면 무시되야 한다.
    2.  만약 onRejected 이 함수가 아니면 무시되야 한다.
  2. onFulfilled가 함수일 경우:

    1.  반드시 promise 가 충족된 다음에 호출되야 하며 첫번째 인수로 promise의 값이 주어져야한다.  it must be called after promise is fulfilled, with promise’s value as its first argument.
    2. promise가 충족되기 전에는 결코 호출되서는 안된다. it must not be called before promise is fulfilled.
    3. 한번 이상 호출되서는 안된다.
  3. onRejected가 함수일 경우:

    1. it must be called after promise is rejected, with promise’s reason as its first argument.
    2. it must not be called before promise is rejected.
    3. it must not be called more than once.
  4. onFulfilled or onRejected must not be called until the execution context stack contains only platform code. 3.1.

  5. onFulfilled and onRejected 반드시 함수로써 전달되야 한다. (예: this 값이 없어야 한다). 3.2

  6. then은 하나의 promise에 대해 여러번 호출될 수 있다.

    1. If/when promise is fulfilled, all respective onFulfilled callbacks must execute in the order of their originating calls to then.
    2. If/when promise is rejected, all respective onRejected callbacks must execute in the order of their originating calls to then.
  7. then은 반드시 promise를 리턴해야 한다 3.3.

    promise2 = promise1.then(onFulfilled, onRejected);

    1. If either onFulfilled or onRejected returns a value x, run the Promise Resolution Procedure [[Resolve]](promise2, x).
    2. If either onFulfilled or onRejected throws an exception epromise2 must be rejected with e as the reason.
    3. If onFulfilled is not a function and promise1 is fulfilled, promise2 must be fulfilled with the same value.
    4. If onRejected is not a function and promise1 is rejected, promise2 must be rejected with the same reason.

Promise 충족 절차

The promise resolution procedure is an abstract operation taking as input a promise and a value, which we denote as [[Resolve]](promise, x).  x가 thenable이면 promise처럼 동작한다는 가정하에 x의 상태를 promise에 설정한다. 그렇지 않다면 promise는 x의 값으로 충족된다.  If x is a thenable, it attempts to make promise adopt the state of x, under the assumption that x behaves at least somewhat like a promise. Otherwise, it fulfills promise with the value x.

This treatment of thenables allows promise implementations to interoperate, as long as they expose a Promises/A+-compliant then method. It also allows Promises/A+ implementations to “assimilate” nonconformant implementations with reasonable then methods.

[[Resolve]](promise, x),코드를 실행하면 다음과 같은 절차를 따른다:

  1. x가 promise와 같은 객체이면 promise를 취소하고 (rejrect) TypeError를 이유로 설정한다.  If promise and x refer to the same object, reject promise with a TypeError as the reason.

  2.  x가 promise이면 그 상태를 적용한다. If x is a promise, adopt its state 3.4:

    1. x값이 pending이면 x가 충족되거나 거부될 떄까지 promise는반드시 pending 상태로 유지되야 한다.  If x is pending, promise must remain pending until x is fulfilled or rejected.
    2.  x가 충족되면 promise는 같은 값으로 충족된다. If/when x is fulfilled, fulfill promise with the same value.
    3.  x가 거부되면 promise도 같은 이유로 거부된다. If/when x is rejected, reject promise with the same reason.
  3.  그외 x가 객체이거나 함수인 경우, Otherwise, if x is an object or function,

    1. Let then be x.thenthen.call(x) 하라.    3.5

    2.  x.then의 결과로 예외 e를 받게되면 promise를 거부하고 이유를 e로 설정한다. If retrieving the property x.then results in a thrown exception e, reject promise with e as the reason.

    3. then이 함수이면 x를 호출객체 this로 하여 호출하되 resolvePromise와 rejectPromise를 인수로 전달한다. If then is a function, call it with x as this, first argument resolvePromise, and second argument , where:

      1. If/when resolvePromise is called with a value y, run [[Resolve]](promise, y).

      2. If/when rejectPromise is called with a reason r, reject promise with r.

      3. If both resolvePromise and rejectPromise are called, or multiple calls to the same argument are made, the first call takes precedence, and any further calls are ignored.

      4. If calling then throws an exception e,

        1. If resolvePromise or rejectPromise have been called, ignore it.
        2. Otherwise, reject promise with e as the reason.
    4.  then이 함수가 아닐경우 promise는 x로 충족된다. If then is not a function, fulfill promise with x.

  4.  x가 객체도 아니고 함수도 아니면 promise는 x로 충족된다. If x is not an object or function, fulfill promise with x.

If a promise is resolved with a thenable that participates in a circular thenable chain, such that the recursive nature of [[Resolve]](promise, thenable) eventually causes [[Resolve]](promise, thenable) to be called again, following the above algorithm will lead to infinite recursion. Implementations are encouraged, but not required, to detect such recursion and reject promise with an informative TypeError as the reason. 3.6

Notes

  1. Here “platform code” means engine, environment, and promise implementation code. In practice, this requirement ensures that onFulfilled and onRejected execute asynchronously, after the event loop turn in which then is called, and with a fresh stack. This can be implemented with either a “macro-task” mechanism such as setTimeout or setImmediate, or with a “micro-task” mechanism such as MutationObserver or process.nextTick. Since the promise implementation is considered platform code, it may itself contain a task-scheduling queue or “trampoline” in which the handlers are called.

  2. That is, in strict mode this will be undefined inside of them; in sloppy mode, it will be the global object.

  3. Implementations may allow promise2 === promise1, provided the implementation meets all requirements. Each implementation should document whether it can produce promise2 === promise1 and under what conditions.

  4. Generally, it will only be known that x is a true promise if it comes from the current implementation. This clause allows the use of implementation-specific means to adopt the state of known-conformant promises.

  5. This procedure of first storing a reference to x.then, then testing that reference, and then calling that reference, avoids multiple accesses to the x.then property. Such precautions are important for ensuring consistency in the face of an accessor property, whose value could change between retrievals.

  6. Implementations should not set arbitrary limits on the depth of thenable chains, and assume that beyond that arbitrary limit the recursion will be infinite. Only true cycles should lead to a TypeError; if an infinite chain of distinct thenables is encountered, recursing forever is the correct behavior.


CC0 
To the extent possible under law, the Promises/A+ organization has waived all copyright and related or neighboring rights to Promises/A+ Promise Specification. This work is published from: United States.