2018년 4월 24일 화요일

개인 프로젝트를 하지 못하는 이유

개인프로젝트는 결국 '내가 쓰고 싶어서' 라는 동기가 필요.

내가 쓰려면 결국 웹, 데탑앱 또는 모바일인데 나는 데탑을 주로 리눅스를 쓰므로 저기서 데탑은 리눅스 환경.

또 한 가지는, 개인프로젝트는 돈 받고 하는 것이 아니므로 열받는 것이 없어야 함. 열받는 것이 없음이라 함은 아래의 조건 중에 걸리는 것이 없거나 적어야 한다는 의미.

  • 언어 자체가 괜찮을 것
  • IDE 나 언어의 툴이 왠만큼 갖추어져 있을 것
  • IDE 와 코드의 정적분석툴이 잘 갖추어지려면 결국 정적타입 언어일 수밖에 없음
  • 문서를 포함한 프레임웍이 갖추어져 있을 것
이래저래 적어도 몇 군데는 꼭 걸림.

  • vala - 언어는 나쁘지 않은데 IDE 가 없음
  • C - 2018년에 응용앱 짜는 데 C... 논할 가치가 없음
  • C++ - 언어 자체를 싫어함. 스펙 두꺼운 언어를 제일 싫어함
  • JavaScript - 정적타입이 아니고.. JavaScript horrible language 가 자동완성으로 뜸
  • Dart - 진짜 다른 점 다 괜찮은데 망한 언어
  • Go - 언어는 괜찮은데 GUI 프레임웍이 없음

결국 개인프로젝트는 못 하는 걸로.. 이 상태가 몇 년 째

DART 언어

angular component, flutter 는 매력적. 언어 하나를 배워서 웹앱과 준 네이티브 모바일 앱을 만들 수 있다는 것은 큰 장점.

그러나 무슨 짓을 해도 떠오르지 않는 인기가 문제인데..

일단 개인프로젝트에 써보려는 중.

2018년 4월 11일 수요일

GCC와 Clang의 RAII

GLib 코딩을 하다가 g_autoptr() 이라는 매크로가 보이길래, C로 또 무슨 흑마술을 부렸나 살펴봤더니 RAII (Resource acquisition is initialization) 기법을 가능하게 하는 확장이 생겼습니다. cleanup 이라는 이름의 확장입니다. 다음과 같은 형태로 쓸 수 있습니다.


void clean_up(int *final_value)
{
  printf("Cleaning up\n");
  printf("Final value: %d\n",*final_value);

}

int main(int argc, char **argv)
{
  /* declare cleanup attribute along with initiliazation
     Without the cleanup attribute, this is equivalent 
     to:
     int avar = 1;
  */
  
  int avar __attribute__ ((__cleanup__(clean_up))) = 1;
  avar = 5;

  return 0;
}
다음에는 간단한 ref count 시스템을 만들어봐야겠군요 :-)

2016년 4월 26일 화요일

Mocks Aren't Stubs



마틴 파울러의 Mocks Aren't Stubs라는 글 소개. 이전에 사내에서 메일로 보냈던 글
-----------------------------------

Mocks aren't stubs 라는 제목의 마틴 파울러의 에세이를 요약해보았습니다.
http://martinfowler.com/articles/mocksArentStubs.html

마틴 파울러는 이 에세이에서 테스트 목적으로 진짜 객체 대신에 사용하는 객체들을 부르는 이름으로 Gerard Meszaros 가 사용한 용어를 따라 "테스트 더블"을 사용합니다. "스턴트 더블"을 응용한 이름입니다.

테스트 더블의 대표적인 사례로 다음을 들고 있고 각각을 다음과 같이 설명합니니다.


  • dummy - 전달은 되지만 실제로는 사용되지 않는 객체. 보통은 함수 파라메터를 채우는 때 사용됩니다.
  • fake - 실제로 동작하는 구현을 포함하고 있지만 지름길들을 이용하고 있고 상업적 용도로 사용할만한 구현은 아닌 것. 메모리 DB를 예로 들고 있습니다.
  • stub - 테스트 도중에 예상되는 값을 반환할 수 있도록 만들어져서 다른 결과값은 주지 못하는 객체입니다.
  • mock - 이 에세이에서 중점적으로 설명하고 있는 대상입니다. "제목은 mock은 stub이 아니다" 이지만 실제로는 mock과 mock이 아닌 것으로 나눠서 설명하는 형태에 가깝습니다.


다른 세 가지의 test double과 비교해서 mock은 확연하게 구분되는 특성이 있는데, 그것은 state를 예측할뿐만 아니라 behavior도 예측한다는 것입니다. 테스트 도중에 email을 보내는 내용을 포함하는 클래스를 test double로 대체한 다음의 코드에서 이것을 볼 수 있습니다.

아래는 stub을 이용할 때의 테스트 코드입니다. 주문을 받고 창고에 재고를 확인하고, 부족한 경우에 이메일을 발송하는 과정을 테스트하는 코드입니다. 자바로 작성되어 있습니다.


class OrderStateTester...
  public void testOrderSendsMailIfUnfilled() {
    Order order = new Order(TALISKER, 51);
    MailServiceStub mailer = new MailServiceStub();
    order.setMailer(mailer);
    order.fill(warehouse);
    assertEquals(1, mailer.numberSent());
  }

...

}
MailService 클래스의 numberSent를 호출해서. 내부의 값, state를 확인합니다. 반면에 mock을 이용하는 테스트는 다음과 같습니다.

class OrderInteractionTester...
  public void testOrderSendsMailIfUnfilled() {
    Order order = new Order(TALISKER, 51);
    Mock warehouse = mock(Warehouse.class);
    Mock mailer = mock(MailService.class);
    order.setMailer((MailService) mailer.proxy());

    mailer.expects(once()).method("send");
    warehouse.expects(once()).method("hasInventory")
      .withAnyArguments()
      .will(returnValue(false));

    order.fill((Warehouse) warehouse.proxy());
  }

...

}
Mock을 이용할 때는 mailer.expects(once()).method("send") 라는 코드를 통하여, 상태값이 아니라 send라는 메소드가 호출되는 동작을 예상하고 이것의 일치 여부를 확인하는 것을 볼 수 있습니다. 이렇게 state의 값이 아니라 behavior를 예상하는 mock 객체의 활용은 BDD(Behavior Driven Development)로 이어집니다. 더 자세한 내용을 알고 싶으시면 서두에 첨부한 마틴 파울러의 에세이를 직접 읽어보시면 좋을 것으로 생각됩니다. 감사합니다.

2016년 4월 19일 화요일

CSP란 무엇인가?

Communicating Sequential Processes 가 무엇인가? 무엇때문에 내가 관심을 가지고 있고 무엇을 기대하고 있는가에 대한 간단한 소개.

위키피디아에서는 CSP를 다음과 같이 소개하고 있다.

In computer science, communicating sequential processes (CSP) is a formal language for describing patterns of interaction in concurrent systems. It is a member of the family of mathematical theories of concurrency known as process algebras, or process calculi, based on message passing via channels.

bullet item으로 만들어보면,

  • formal language
  • describing patterns of interaction in concurrent systems.
  • process algebras, process calcui
  • based on message passing via channels.

CSP 로 기술할 수 있는 세계는 동시성을 가진 object 들이 message passing 방식으로 커뮤니케이션하는 세계이다. CSP는 이러한 상황을 formal language 로 묘사할 수 있게 해준다.

다른 한편으로는 이것은 process algebra 를 가능하게 한다. 어떤 시스템에서 데드락이 발생한다/하지 않는다와 같은 판정을 수식으로 풀어서 증명할 수 있게 해주는 도구가 된다.


만약에 CSP에 충실한 언어가 있다면, 동시성이 발생하는 어떤 시스템을 CSP로 기술하고, 거기서부터 시작해서 수학적으로 문제가 발생할 소지가 있는지를 검증한 후, 이것을 프로그래밍 코드로 전환할 수 있을 것이다. Go, OCAML 등이 CSP에 강한 영향을 받은 언어로 wikipedia에 이름을 올리고 있다.

이러한 접근이 흥미롭게 들린다면 이 책은 읽어볼만한 가치가 있을 것이다.

2016년 4월 18일 월요일

2015년 6월 26일 금요일

초심자의 첫번째 언어

코딩 초심자의 첫 번째 언어로는 크게 두 가지 의견이 대립한다고 생각한다. 첫 번째는 C이고, 다른 하나는 해당 시기의 패러다임을 대표하는 적당한 하이레벨 언어이다. 이 둘은 각각 다른 전제를 깔고 있다.


C를 첫 번째 언어로 가르치자는 주장은 컴퓨터가 결국 상당히 오랜 기간동안 노이만 머신이나 그와 유사한 형태의 기계일 것이라는 가정을 깔고 있다.

C의 로우레벨함에 진저리를 내는 사람도 많지만, 어쨌거나 C는 어셈블러 코딩을 피하기 위한 언어로 일정 정도의 추상화를 제공하기 위해서 등장한 언어였고 등장할 당시에는 어셈블러에 비해 30%의 오버헤드를 떠안은 상태로 성공적인 OS 프로그래밍을 할 수 없으리라고 여겨지기도 했다.

그렇다면 C는 구체적인 CPU 아키텍쳐를 감추고 무엇을 공통요소로 추출해서 무엇으로 추상화하는가? 나는 그것이 결국 노이만 머신이라고 생각한다. C언어를 통해서 바라본 컴퓨터는 각 리소스가 메모리 주소로서 접근되고 그것을 처리하는 장치가 있는 장치이다.

이 가정이 C언어를 첫 언어로 가르치자는 주장을 정당화하는지 여부를 평가하자면 크게 두 가지를 평가해야 한다고 본다. 한 가지는 이 가정이 현실에 부합하는가, 그리고 다른 한 가지는 그것이 사실이라면 유의미한가.

나는 가정이 현실에 부합한다고 본다. 굳이 C언어를 가르쳐야 하느냐는 의문과 함께 cs101 언어로 자바, 파이썬 등이 채택되는 동안, 여전히 우리의 컴퓨터는 노이만 머신에 기반한 구조를 가지고 있다.

문제는 이 사실이 유의미하느냐는 문제이다. "컴퓨터는 노이만 머신에 기반한 구조를 가지고 있고 C언어는 이에 가깝다. 그런데 그래서 그게 뭐?" 라는 질문은 첫 번째 질문에 대한 대답보다 확신에 차서 대답하기는 힘들다.

컴퓨터의 동작 원리를 이해하기 위해서 C언어를 가르쳐야 한다면 정말로 그것으로 설명이 되는가? C언어를 배운다고 해서 아키텍쳐와 OS 과목에서 가르치는 원리들 - 메모리 로컬리티와 작업 내용이 캐쉬 위에 올라가느냐 또는 분기 예측의 성공과 실패 여부가 속도에 미치는 영향, 가상 메모리와 페이징 및 메모리의 파편화, 쓰래슁 등을 이해할 수 있는가? 이런 로우레벨한 문제를 고려한 코드를 짜는 데 C언어로 코딩을 배우는 것이 도움이 되는가? 실상 생각해보면 별 도움이 되지 않는다. C언어로 메모리를 수동관리해가면서 코드를 짜는 것은, 로우레벨한 문제의 상당히 한정된 일부를 다뤄보는 데 그칠 뿐이다.


두 번째 입장, 적절한 하이레벨 언어로 코딩을 가르치자는 입장은 computational thinking 이라고 부르는 어떤 정신을 심어주는 것이 핵심적인 문제이고 로우레벨한 문제는 이것을 가능하게 하는 수단이지 그 자체가 목적이 아니라는 입장이라고 요약하고자 한다. 또한 위에서 언급한대로, 실상 로우레벨한 문제는 그 자체로 배워야 할 거리들을 형성하고 있어서, "노이만 머신으로 추상화한 언어"인 C언어에서는 이미 다룰 수 없는 부분을 많이 가지고 있다. 그건 C언어로 코딩을 배운다고 해결될 문제가 아니라, 그 자체로 따로 배워야 할 문제이다.

이런 주장에 대해서 내가 가진 의구심은, 지금까지 관찰되어온 바에 의하면 코드를 다른 어떤 것으로 추상화한 것보다는 노이만 머신으로 추상화한 것이 더 오랫동안 유효했다는 점이다. lisp의 역사는 사실은 C보다도 길고, 각종 사물에 대한 메타포로 코딩하는 OOP에 대한 열광도 이제 조금은 식은 이 시점에, 자바같은 극단적으로 명사(noun)적인 사고를 강요하는 언어가 장기적으로 도움이 되었을까, 함수형 패러다임은 과연 컴퓨터가 노이만 머신에서 멀어질 때까지 유효할까 등에 의문을 가지게 된다.

여전히 컴퓨터는 노이만 머신에 가까운 구조로 되어 있고, 이 사실은 적어도 어떤 영역에서 작업을 하는 사람들에게는 중요하다. 위에 언급한 '어차피 따로 배워야 하는 로우레벨한 영역에 대한 지식들'도 사실 노이만 구조를 이해할 때 더 쉽게 이해할 수 있다.


이 둘 사이에서 나는 어떤 강한 의견을 가지고 있지는 않고 양자를 다 부분 긍정하면서 관전할 뿐이다.

다만 이런 관점에서, 첫 번째 언어로 무엇을 택해야 한다는 것은 없지만 받아들일 수 없는 언어들은 있다.

C++은 추상화되지도 않았고 딱히 노이만 머신으로 추상화하는 언어도 아니어서 둘 모두에 속하지 않고, js를 가르친다면 차라리 함수의 first class citizen 특성을 부각시켜서 가르치는 게 맞지 로우레벨 접근 안 되는 C로 가르치는 것은 반대이다.

결국 전형적인 내 입장이 되고 만다. 꼭 이것이어야 한다는 것은 없다, 이것은 용납 불가능하다는 목록은 있다.