I thought I've written exactly the same blog post last year, but I guess I didn't. Maybe I was smart enough not to show this negative feeling.

It's almost the end of year. Every year, I've been thinking the same thing in this season and anxious. That is my skill, in one word. It might also be called my career path, knowledge or experience. I just don't know how I can describe what I'm worrying for.

Since 2004, I've been working as a software developer. There are couple of years of blank periods but most of my career is being Java developer, good or bad. When I started my career, I was just an ordinary newbie who had a bit of programming skill and assigned to the *deadline is already decided* project. Everything was new including somewhat deadline was there but no specification situation, and there were lots of things to learn, like how to capture screen shot and put it into excel sheet... At that moment, struts 1.0 was there and the concept of DI has just come. After 2 years, I quit the first job and became server administrator... sort of.

In year 2009, I've moved to The Netherlands. At that time, I had some blank as a Java developer. So I didn't know when CI is appeared. DI was still there but a bit brushed up. I could use Java annotation instead of writing huge application-context.xml. I still had lots of things to learn, however I just noticed that I was just learning the usage of libraries. If those libraries disappeared in 5 years, then this knowledge is just useless. Luckily, I've met Scheme and started writing own implementation to build some tools I can use on daily routine.

Writing a Scheme implementation gave me lots of challenges. I wasn't a good C programmer, well am still not, though. How function pointer works, how x86 works, how to retrieve stack area information, difference between POSIX and Windows, those were all new for me. I've never read C89 or C99 specification, so I will never be a C expert, but at least now I know where to look at if I need to find something.

If you write an implementation, then you also need to write libraries. Fortunately, or unfortunately, there's not much Scheme code. So I needed to write loads of code. If I see the code written in very first period of my Scheme life, those look ugly. I can't say I understand how Scheme works perfectly and I can write universal beautiful code. All what I know is how to write workable code and at least that works for me. Maybe I can say I also now the basic concept of paradigms which are used in Scheme programming, such as first class object and CPS.

7 years later, I'm still anxious. Maybe I feel like I know nothing essential. I know numbers of libraries and how those works. I know how to implement TLS or other network protocols. But are these essential? I only have vague idea what's essential knowledge is. It should be knowledge that I can use; even if I need to make software with a language I've never used; in the different IT field; after 20 years so on. And maybe I've already known that there's no such thing. And maybe the fact that I knew this reality makes me more anxious.

If I become a high skilled programmer, would this be gone? It might be better not to think about this and just study hard since I know I need to know more.




SagittariusはCommon Lispから移植したOAuth1.0を扱うライブラリを持っている。っが、このライブラリ将来OAuth2に対応させれるようにしたのかキーワード引数が大量にあり今一使い勝手が悪いい。っで、最近職場でOAuth2上に構築されたプロトコルの一つであるOpenID Connectを使うということが持ち上がっていることもあり、OAuth2のライブラリがいるかなぁという機運が高まってきている。

The OAuth 1.0 protocol ([RFC5849]), published as an informational document, was the result of a small ad hoc community effort. This Standards Track specification builds on the OAuth 1.0 deployment experience, as well as additional use cases and extensibility requirements gathered from the wider IETF community. The OAuth 2.0 protocol is not backward compatible with OAuth 1.0. The two versions may co-exist on the network, and implementations may choose to support both. However, it is the intention of this specification that new implementations support OAuth 2.0 as specified in this document and that OAuth 1.0 is used only to support existing deployments. The OAuth 2.0 protocol shares very few implementation details with the OAuth 1.0 protocol. Implementers familiar with OAuth 1.0 should approach this document without any assumptions as to its structure and details.
太字にした一文があるため、廃止されているとはいえ両方サポートした方がよさげな感じがしている。例えばWikipediaのList of OAuth providersのページによれば、OAuth1しかサポートしていないプロバイダーも結構ある(Bitbucket、Flickr、Tumbler辺りは個人的に使うかもしれない)。

  • (rfc oauth)
    • (rfc oauth v1.0)
      • client and so?
    • (rfc oauth v2.0)
      • client and so?
  • (rfc oauth1)
  • (rfc oauth2)
無難に分けた方がいい気がするなぁ、変に統合すると混乱しそうだし。現在ある(net oauth)ライブラリはそのままにするが、deprecatedという形にすればいいかな。うまいことやれるなら新しいライブラリを下請けにする形にしたいが、そこまで手が回るかは疑問。



この記事はLisp Advent Calendar 2016の19日目の記事です。

最近c.l.s.に面白い投稿があった。これである。 要約をすると、R7RSに以下の一文を追加しようという話になる。
It is an error to invoke the continuation of a top-level expression or the expression of a top-level definition more than once.
(define-library (foo)
  (import (scheme base))
  (export reload count)
    (define counter (vector 0))              ;; (1)
    (define (count) (vector-ref counter 0))  ;; (2)
    (define reload (call/cc (lambda (k) k))) ;; (3)
    (vector-set! counter 0 (+ 1 (count)))))  ;; (4)

(import (scheme base) (scheme write) (foo))  ;; (5)

(unless (>= (count) 10)
  (display (count))
  (reload reload))
;; end of the file


継続はSchemer以外のLisperには馴染みのない概念かもしれないので簡単に説明しておく。Schemeの仕様書を読むとなんとも面倒な言葉で書かれているが、厳密には多少違うが言ってしまえばコールグラフのことである(Clojure/Conjではスタックだと断言していた。まぁその通りである。)。 上記のコードでは以下のようにプログラムが実行される:
  (??) --> (1) --> (2) --> (3) --> (4) --> (??)



例えばこのプログラムが1ファイルに書かれていたとしよう。そして、処理系は一つの式を読み込み、実行という順序でファイルを処理したとする。この場合に(??)にくるのは次の式を読み込むという処理になるはずだ。そうすると、保存したreloadを起動した際に起きると予測されるのは、コメント;; end of the fileが読み込まれEOFが返されることであると言える(注:unlessから始まる式は既に読まれている)。ファイルの読み込みがEOFを返した場合、通常そのファイルは全て実行されたと解釈されるので、処理は終了するのが筋である。とすれば、この継続をこの位置で起動すると処理が終了すると言える。(必ずしも処理が終了するわけではないことに注意)

さて、c.l.s.の投稿ではLarcenyで上記のプログラムを走らせた場合想定通りに動いたとされている。これはどういうことか?簡単に言えばLarcenyはvan Tonderの展開器を使っているからとなる。もう少し突っ込んで解説をすると、van Tonderの展開器はR5RS上でポータブルにライブラリ機能を追加している。R5RSにはライブラリ機能は存在しないので実行時になんとかやっているわけだ。例えば上記のプログラムは概ね以下のように解釈される。
  (let ()
    (define counter ...)
    (define (count) ...)
    (define reload ...)
    (vector-set! ...)
    (register-library '(foo) ...)
  (resolve-import ...)
  (unless (>= (count) 10) ...))
このようにプログラムが展開された場合、(??)に当たる部分は何になるだろうか?そう、(register-library ...)の部分である。そして、プログラム全体が一つの式として解釈されているので、次の式を読み込む必要がない。これによりLarcenyでは見かけ上期待した結果が帰ってくるということになる。この問題はこの2つだけが予測される結末ではないのが面白いところである。





REPL上ではどうだろうか?REPLでは(vector-set! ...)が実行された後に次の式を読み込むために一旦制御が入力待ち状態になる。つまり、reloadの起動は(vector-set! ..)を実行し入力待ちの状態になるはずである(少なくともSagittarius上ではそうなる)。これももちろんREPLの実装依存になるだろう。





この記事はLisp Advent Calendarの2日目の記事です。



Working group 2 will develop specifications, documents, and proofs of practical implementability for a language that embodies the essential character of Scheme, that is large enough to address the practical needs of mainstream software development, and that can be extended and integrated with other systems.
The purpose of this work is to facilitate sharing of Scheme code. One goal is to be able to reuse code written in one conforming implementation in another conforming implementation with as little change as possible. Another goal is for users of this work to be able to understand each other's code based on a shared and unambiguous interpretation of its meaning.
The language is not necessarily intended for educational, research, or embedded use, though such uses are not prohibited. Therefore, it may be a "heavyweight" language compared to the language designed by working group 1.
From Charter for working group 2





  • SRFI 1 (scheme list)
  • SRFI 133 (scheme vector)
  • SRFI 132 (scheme sorting)
  • SRFI 113 (scheme set)
  • SRFI 114 (scheme set char)
  • SRFI 125 (scheme hash-table)
  • SRFI 116 (scheme list immutable)
  • SRFI 101 (scheme list random-access)
  • SRFI 134 (scheme deque immutable)
  • SRFI 135 (scheme textual)
  • SRFI 121 (scheme generator)
  • SRFI 128 (scheme lazy-seq)
  • SRFI 41 (scheme stream)
  • SRFI 111 (scheme box)
    ボックスSRFI。ボックスは名前が示す通り単なる箱で、Schemeのオブジェクトをなんでも格納しておくことができるもの。これを使うと明示的に参照渡しが可能になるはず。まぁ、あると便利だけど、なければ(vector obj)で代用できてしまうようなもの。コンパイラが頑張ると最適化してくれるかもしれない。
  • SRFI 117 (scheme list queue)
  • SRFI 124 (scheme ephemeron)
    実装者泣かせSRFIの一つ。キーと値を持つデータ構造で、基本的な部分では弱い参照と一緒なんだけど、値がキーを参照していた際でもGCされるという特徴を持つもの。噂によるとまともに実装されているのはRacketとMIT Schemeくらいらしい。
  • SRFI 128 (scheme comparator)


  •  OrangeDocket: 数値関係
    • Numeric types and operations: 
      • Integer division: SRFI-141
      • Bitwise integer operations: SRFI-142, SRFI-60 or R6RS
      • Fixnums: SRFI-143 or R6RS
      • Flonums: SRFI-144 or R6RS
      • Compnums: John's proposal
      • Random numbers: SRFI-27 plus Gauche's generator
      • Prime numbers: Gauche's prime number library
    • Numeric and semi-numeric data structures
    • Enumerations (なんでこれここにあるんだろう?)
    • Formatting (同上)
  • YellowDocket: 構文関係
    • Low-level macros (有名どころの低レベルマクロがリストされてる)
    • Syntax parameters: SRFI-139
    • Matching (パターンマッチ)
    • Combinators
    • Conditional procedures (if等をdefineで定義した感じのなにか?)
    • cond guards: SRFI-61
    • Lambda* (Scheme Workshop 2013に出た論文がもとっぽい)
    • Void (eq?で比較可能なNULLオブジェクト)
    • Named parameters: John's proposal or SRFI-89
    • Generalized set!: SRFI-17
    • and-let*: SRFI2
    • receive: SRFI-8
    • cut/cute: SRFI 26
    • Loops: SRFI-42, foof-loop or Chibh loop
    • Generic accessors/mutators: SRFI-123
    • Conditions (例外、なぜにR6RSではないのか…)
  • GreenDocket: ポータブルに書けない何か
    • File I/O
    • Threads: SRFI-18
    • Real-time threads: SRFI-21 (分ける必要あるのか?)
    • Socket: SRFI-106
    • Datagram channels (UDP sockets)
    • Timers: SRFI-120 (なんでこれがあるんだろう?)
    • Mutable environments
    • Simple POSIX (Windowsは完全無視ですね、わかります)
    • Access to the REPL (これ完全にR6RS殺しに来てるな…)
    • Library declarations
    • Symbols
    • Interfaces
    • Process ports (紛らわしいけど、プロセスI/Oをポートにリダイレクトする話)
    • Directory ports (ディレクトリをポートみたいに読む、正直紛らわしい)
    • Directory creation/deletion
    • Port operations
    • System commands (Process portsと被り気味な気がする)
    • Pure delay/force (スレッドを使ったdelay/forceっぽい)
  • BlueDocket: ポータブルだけど高度なものたち(portable but advanced things)
    • Time types: SRFI-19
    • Binary I/O
    • Character conversion (要するにR6RSのコーデック的なもの)
    • Parallel promises (pure delay/forceじゃだめなん?)
    • Pathname objects
    • URI objects
    • Unicode character database
    • Environment (紛らわしいけどusernameとかメモリとかを引くためのもの)
    • Trees (リストにあるけど提案なし)