Syntax highlighter

2015-10-24

er-macro-transformer on top of syntax-case

There are numbers of low level hygienic macros in Scheme world. The most famous ones are probably the followings:
  • explicit renaming
  • syntax-case
  • syntactic closure
Of course there are more (e.g. ir, reverse syntactic) but if you discuss low level hygienic macros, then above would usual be the ones.

R6RS has syntax-case and rumour says R7RS would have explicit renaming. According to this article, if implementations have one of them, then the rest can be implemented atop it. I'm wondering is it really true? Very lame conclusion is true. Because Sagittarius uses kind of syntactic closure and implements both explicit renaming and syntax-case. Now, can it be done in a portable way?

So I've wrote this. It seems this can work most of R6RS implementations except Racket. Though I haven't tested on Larceny, Guile and Vicare yet, they are using either Psyntax or van Tonder expander such as Mosh and IronScheme (Psyntax) or NMosh (van Tonder). So should work.

The basic idea of the implementation is very simple. rename procedure is a simple wrapper of datum->syntax. compare is free-identifier=?. Then wrap the returning form with datum->syntax*.

The initial revision of the Gist used mere datum->syntax. This wasn't good enough because the procedure should only accept datum not syntax object. The error was raised by Psyntax implementations and Racket. Then I've been suggested to walk thought the returning form.

I first thought this won't work because traversing and constructing a new form would return a list not a syntax object. However I was just didn't consider thoroughly. If I use syntax-case and quasisyntax (with-syntax could also be), then I can construct syntax object containing syntax object renamed by er-macro-transformer. So I've rewrite the code. Then most of the R6RS implementation seem working. Even Racket seems working if the macro is very simple like the one on the comment.

Now, my question is 'Is this R6RS portable?'. R6RS standard libraries 12.2 says:
The distinction between the terms “syntax object” and “wrapped syntax object” is important. For example, when invoked by the expander, a transformer (section 12.3) must accept a wrapped syntax object but may return any syntax object, including an unwrapped syntax object.
So transformer *MAY* return unwrapped syntax object. Though what I'm doing is returning wrapped syntax object so should be fine. What I couldn't read is whether or not a syntax object can contain syntax object(s) inserted by other transformer. If this is required feature, then this might be a bug of Racket. Otherwise this is not portable.

I hope it's a bug of Racket, then you (not me) can write an explicit renaming SRFI with sample implementation.

For convenience, embedded source.

2015-10-18

カスタムポートとソケットとバッファポート

「と」で繋げるとなんとなくアニメとかのタイトルっぽい感じがするなぁ。

Sagittariusは0.6.9でポート周りにかなりバグを混入した(弄った)のだが、頭を悩ませるバグが顕在化した。それが表題のポートである。どこで使われているかといえばTLSである。

何が問題か?いくつかの問題が合わさってるのではあるんだが、一つはget-bytevector-nとカスタムポートの相性。カスタムポートは要求されたバイト(文字数)を返す必要はないので、例えば1バイトずつ返して呼び出し元に判断させるということができる。例えば以下のようなの
(import (rnrs))

(let* ([pos 0]
       [p (make-custom-binary-input-port
           "custom in"
           (lambda (bv start count)
             (if (= pos 16)
                 0
                 (begin
                   (set! pos (+ 1 pos))
                   (bytevector-u8-set! bv start pos)
                   1)))
           (lambda () pos)
           (lambda (p) (set! pos p))
           (lambda () 'ok))])
  (get-bytevector-n p 3))
;;-> #vu8(1 2 3)
R6RSテストスイーツからの抜粋なのだが、read!手続きは1バイトずつ処理しget-bytevector-nが最終的に何を返すか決定するという形である。カスタムポートが扱うのが有限のデータなら特に問題ないのだが、ソケットのようにいつEOFがくるか分からないものだと割と困るのである。例えばread!の部分がrecvを使っていたとして、あるソケットは要求の半分のデータを受信したする。そうするとget-bytevector-nは残りの半分を取得するためにもう一回read!を呼び、処理はブロックされる。

不定長のデータを扱うのにget-bytevector-nなんて使うなという話なのだが、本当の問題は別のところにある。0.6.9からバッファポートを導入したのだが、こいつとカスタムポートの相性が悪い。何が悪いかと言えば、バッファを埋めるのにget-bytevector-n相当のことがされているのである。カスタムポートを実装したときに、あまり何も考えずにポート側でバイト数を数えるようにしてしまったので複数回の呼び出しが起きるという話なのではある。

解決方法は多分2つくらいあって、
  1. バッファを埋める処理を別枠にする
  2. 現状ポート側でやってることをget-bytevector-nに移す
1.はそこそこadhocな感じがして嫌だなぁ。2.は(99.99%ないけど)別のところに影響が出る可能性がある(もしくは考慮漏れによるバグの混入)。でも2かなぁ、どう考えても。それでとりあえずはバッファの問題は解決するし。

2015-10-15

CPSマクロ

assocをマクロで書いたらどうなるか、ということを考えた。これくらいならそんなに難しい話ではなく、以下のように書けるだろう。
(import (scheme base) (scheme write))

(define-syntax assocm
  (syntax-rules ()
    ((_ key (alist ...))
     (letrec-syntax ((foo (syntax-rules (key)
                            ((_ (key . e) res (... ...)) (key . e))
                            ((_ (a . d) res (... ...)) (foo res (... ...))))))
       (foo alist ...)))))

;; a bit of trick to avoid unbound variable
(define (c d) (list 'c d))
(define d 1)

(assocm c ((a b) (b d) (c d) (d d)))
;; -> (c 1)
取り出せるのであれば、その中身も欲しい。つまり、carcdrだ。これも同じ要領でやればこんな感じで書けるだろう。
(define-syntax cdrm
  (syntax-rules ()
    ((_ (a . d)) d)))

(cdrm (c . d))
;; -> 1
だが、これら二つのマクロはこんな感じでは組み合わせられない。
(cdrm (assocm c ((a b) (b d) (c d) (d d))))
;; -> error
これはcdrmassocmより先に展開されるからである。あるマクロの展開結果を別のマクロで使いたい状況というのはしばしばある。そういうときにはCPSでマクロを書く。最初のassocmをCPSで書いてみよう。
(define-syntax assocm/cps
  (syntax-rules ()
    ((_ k key (alist ...))
     (letrec-syntax ((foo (syntax-rules (key)
                            ((_ (key . e) res (... ...)) (k (key . e)))
                            ((_ (a . d) res (... ...)) (foo res (... ...))))))
       (foo alist ...)))))

(assocm/cps cdrm c ((a . b) (b . d) (c . d) (d . d)))
;; -> 1
このassocm/cpsは最初の引数に次に展開するマクロを受け取ることで、マクロの展開が終わった際に展開結果(この場合は(key . e))を引数kに渡すことを可能としている。要するに単なるCPSであるがこの状態では割と致命的な欠点がある。それは複数のマクロを組み合わせることができないということである。

例えば上記の例でcadrmはどう書くだろうか?普通に考えれば、carmを定義したのち、cdrmを組み合わせて書きたいところであろう。(もちろんゴリゴリ書いてもいいんだけど。) そう(compose f g)みたいなことがしたわけである。
;; I want to write like this!
(assocm/cps (composem cdrm/cps carm) c ((a . b) (b . d) (c . d) (d . d)))
こうなると、単にマクロを受け取って結果を渡すだけではなく、次のマクロが複合マクロかどうかを判別して上手いことやってくれる何かがほしい。こんな感じだろう。
(define-syntax composem (syntax-rules ()))

;; assume k is CPS macro
(define-syntax extract/cps
  ;; it's a bit awkward to have own name in literals
  ;; but this saves me a lot
  (syntax-rules (composem extract/cps)
    ((_ (composem k) args ...) (k args ...))
    ((_ (composem k ...) args ...)
     (extract/cps "flatten" () (k ...) (args ...)))
    ;; flatten nested composem
    ((_ "flatten" (cps ...) ((composem k ...) k* ...) args)
     (extract/cps "flatten" (cps ... k ...) (k* ...) args))
    ((_ "flatten" (cps ...) (k k* ...) args)
     (extract/cps "flatten" (cps ... k) (k* ...) args))
    ((_ "flatten" (cps ...) () (args ...))
     (extract/cps (extract/cps cps ...) args ...))
    ;; extract/cps keyword
    ((_ (extract/cps (composem k)) args ...) (k args ...))
    ((_ (extract/cps (composem k k* ...)) args ...)
     (k (extract/cps (composem k* ...)) args ...))

    ((_ (extract/cps k) args ...) (k args ...))
    ((_ (extract/cps k k* ...) args ...)
     (k (extract/cps (composem k* ...)) args ...))
    ;; short cut
    ((_ k args ...) (k args ...))))
多少無理やり感があるので(extract/cpsリテラルとか)もう少し綺麗にならないかと思ったりはするのだが、まぁとりあえずこんな感じでいいだろう。これを使って上記のassocm/cpsは以下のように書き換える。
(define-syntax assocm/cps
  (syntax-rules ()
    ((_ k key (alist ...))
     (letrec-syntax ((foo (syntax-rules (key)
                            ((_ (key . e) res (... ...)) 
                             (extract/cps k (key . e)))
                            ((_ (a . d) res (... ...)) (foo res (... ...))))))
       (foo alist ...)))))
さらにcarm/cpscdrm/cpsをこんな感じで定義して、最後のkvaluesmとして定義しよう。CPSマクロの最後に展開されるマクロはCPSではないことに注意しよう。
(define-syntax cdrm/cps
  (syntax-rules ()
    ((_ k (a . d)) (extract/cps k d))))

(define-syntax carm/cps
  (syntax-rules ()
    ((_ k (a . d)) (extract/cps k a))))

(define-syntax valuesm
  (syntax-rules ()
    ((_ args) args)
    ;; this isn't really values...
    ((_ args ...) (args ...))))
こうするとassocmから見つかった値のcadr部分をとるマクロは以下のように書ける。
(assocm/cps (composem cdrm/cps carm/cps valuesm) c ((a b) (b d) (c d) (d d)))
;; -> 1
ちなみに、このコードGaucheでは(まだ)動かないので(すぐ直されると思うけど)、実際に動かしてみたい場合はSagittarius、Chibi、Larcenyのいずれかを使うといいだろう。

ちなみに、この手のコードは3日もすると自分でも理解不能になる危険を孕んでいるので使用する際は十分に留意した方がいいだろう。こういったマクロはだいたOleg氏がまとめているので、メタプログラミングの深淵を覗きたい方はそちらを参照されたい。この辺とか。

2015-10-12

Small Scheme or large Scheme?

2 topics about the size of Scheme were posted on c.l.s. One was rather branch of other topic:How many R6RS users and how much code out there?. And the other is indirectly suggesting it: Question about vote of RnRS (the poster mentioned about the change between R5RS and R6RS as drastic change so seems it's about the size.) Even though all what I wanted to say is already said by Taylan on the first topic I've mentioned, I want to write something about the size so bare with me :)

The point of this topic for me is the definition of small or large. The poster said it is useful enough for educational purpose. I agree with it. If I need to add a bit of my opinion about this, I would say the languages which has proper design for the topic of the class are useful enough for educational purpose as long as students don't use convenient libraries. Java is fine for OOP, C++ is fine for OOP and meta programming, Mathematica is excellent for math, etc. So they can also be programming languages for educational purpose, right? Now are they small?

The answer for me is no. Especially if you see C++'s specification, it's more than gigantic even human beings couldn't understand, IMHO (are there people who understand all the spec?). I wouldn't say it's one of beautifully designed language, but it's powerful enough to cover other purposes including professional use . Then, should Scheme be this much huge to make all programmer happy?

My answer is again no. It's too complicated, it's piling up features on top of other features on top of other, lemme quit. One of the reason why C++ is piling up those features, I believe, is that it doesn't have enough abstraction to make language self growing. Most of programming language don't have this type of feature such as defining new syntax. Or if they have it, it'd be rather complicated to use, either deliberately or accidentally. If it's deliberately, then the designer of the language doesn't want users to use it casually. If it's accidentally, then it's not considered well but made rather adhoc. The first decision is understandable, sometimes those things are not really needed and don't want users to summon daemons from their nose.

Now what's the definition of small in Scheme specification? In my opinion, there is no need to pile up features but it can grow by itself. Let me elaborate what it means.  Currently there're on going discussion about hashtable on SRFI. This might be a good example to do it. Is hashtable required by small language as Scheme? Well, my answer from bottom of my heart is yes but rational answer is no. Why no? It can be implemented by vector and record. Now one of the SRFIs also mentioning weak hashtable. This is rather interesting. Implementing this data structure can not be done neither in range of R6RS nor R7RS. So this seems required, right? Wait a sec, there's a draft SRFI about ephemeron. If you use this, then you can implement weak hashtable using vector, record and ephemeron. So the absolute requirement to have is this one. Hurrah, the language spec is kept small enough!

IMO, this is a bit too extreme. Each time users need to make own utility libraries for those common data structure is ridiculous. Then here comes R7RS-large process. The purpose, in my understanding, of this process is that keeping core language absolutely minimum and put a collection of those commonly used things in its specification. So implementations may or may not support all of them. Oops, again, what's absolutely minimum?

Unfortunately, I don't have generic answer for this and, I believe, neither most of Schemers do. The only thing I do have now is that it's not enought to be perfect language which can solve all problems in this world. Concurrency, networking, weak data, etc. These are not in the specification (maybe yet) but absolutely needed. If there's something lacking, then language specification should grow even if it's got bigger.

The world of computer is growing like speed of light. Problems to be solved are zillion. Too small wouldn't solve. We need small enough.

2015-10-09

bound or free identifier

I've just fixed the bug of incorrect usage of free-identifier=? during macro expansion. As my memo and maybe good to share what I've learnt.

Firstly, have a look at this piece of code:
(import (rnrs))

(define-syntax foo
  (lambda (x)
    (syntax-case x ()
      ((_ (t1 t2))
       ;; what should be print?
       (begin (display (free-identifier=? #'t1 #'t2)) (newline)
              (display (bound-identifier=? #'t1 #'t2)) (newline))
       #''ok)
      ((_ (t* ...) a b ...)
       #'(foo (t* ... t) b ...))
      ((_ a ...)
       #'(foo () a ...)))))
(foo 1 2)
If you can immediately see what's printed, then you can skip the next paragraph :)

The difference between bound-identifier=? and free-identifier=? is that the first one only sees where the given 2 identifiers were  created and the second one sees the actual bindings are the same or not. In the above example, identifier ts are created in different places, more precisely different macro expansion process. If you expand the macro manually, then it would look like this:
(foo 1 2)
;; -> (foo () 1 2))
;; -> (foo (t) 2)) ;; <- where the first t is created 
;; -> (foo (t t))  ;; <- the second one is created here in the different macro expansion
;; 'ok
If 2 identifiers whose names are same are created in different macro expansion, then comparing bound-identifier=? should return #f.free-identifier=?, on the other hand, should return #t because those identifiers are not bound to anything thus they have the same binding (unbound variable) and also have the same name (t). (This is what I understood the behaviour of those 2 procedures. Correct me, if I'm wrong.)

Now the bug was related to this difference. The detail is here. In the description, it says free-identifier=? returns #t against pattern variables t but this is correct behaviour. What I did wrong was using free-identifier=? to compare pattern variables during expanding template variables. Moreover, compiler for syntax-case renamed pattern variables which must be preserved so that expander can use bound-identifier=? to compare pattern variables.

If I know what's wrong, then fixing it is not a big problem. Just adding extra check for pattern variable and use bound-identifier=?. Done! I hope this would be the last article related to macro bug... (feeling won't though)

2015-10-08

マクロバグ

何回目だろうこのネタ。もういい加減尽きたと信じたかったが、そうもいかないらしい。

バグの報告は以下のツイート
突き詰めていくと、テンプレート変数を割り当てていく部分で使用しているfree-identifier=?がこの条件だと全ての一時パターン変数に対して#tを返すということが分かった。adhocに直すならこういう場合の比較に対しては#fを返すようにすればいいのだが、コードを眺めていてふと思った、「こいつらbound-identifier=?で比較しないとまずくね?」と。

単純にこの二つの手続きを置き換えるだけなら何の問題もなく、こんな記事も書いてはいないのだが、そうは問屋が卸してくれなかった。問題になるのは、with-syntax等でラップされた式の中で束縛されたテンプレートを返すようにした場合である。例えばこんなの:
(syntax-case x ()
  ((_ (k ...))
   (with-syntax (((e ...) (gen)))
     #'(lambda (x) (syntax-case x (k...) e ...)))))
具体的にはsyntax-rulesがこんな感じの定義なんだけど、パターン変数がそのままマクロによって生成されるsyntax-caseで使われているのがまずい。現状の実装ではマクロの展開が走ると問答無用で識別子がリネームされてしまうので、パターンのkとテンプレートのkが別の識別子として束縛されてしまう(つまりbound-identifier=?#fを返す)。

あれ、待てよ。パターン変数として束縛された識別子はマクロ環境で束縛されているので、リネームの際にそれを避けるようにすれば無用なリネームが発生しないことになるな。その方向でいくか。やはり問題は一度書き出すとなんとなく解決策がでてくるものだな。まだ解決してないけど。

2015-10-07

Timezone related bugs

Since Sagittarius 0.6.7, it has timezone object. The rationale behind this is pretty simple. Before it used localtime and some other C APIs to get proper local timezone offset. I wasn't unhappy until I needed to handle other timezone offsets. I don't remember exact situation but related to time conversion. Unfortunately, on POSIX there is no way to treat timezone as objects (as far as I could research), so I've decided to implement own timezone handling.

Timezone is related to physical location. Of course, you can change your computer's setting to deceive yourself. I wasn't one of those people and that bit me. I've faced 2 timezone related bugs. Both could only happen in particular places, Japan and country where no summer time. Let me share the bug story. Starting from the first one.

There is IANA TZ database and I'm using it to find proper timezone offset. If you build Sagittarius from repository, then the pre-build process, not cmake but dist.sh, downloads TZ database and compiles it to S-expression. It's not too bad. The only bad thing is that it can't handle any rules not written in the TZ database, such as Japan.

Asia/Tokyo timezone has rather weird rules. According to the TZ database, Japan had summer time between 1948-1951. On the comment, it clearly says this is used only on US military base, for your information, so officially Japan didn't have it, though. Funny thing is that this rule, named Japan, is associated to Asia/Tokyo timezone and it's active now (2015 current). Additionally, the rule doesn't have definition of after 1951. So what should happen? Maybe I didn't read all the comment or how the rules defined properly so I missed something. Anyway, the previous behaviour of handling this situation was signaling an error. Which, of course, caused problem. The biggest one was Sagittarius couldn't be built in Japan.

Thanks to the comment on this blog, I could notice there was such a problem. Other than that, this would stay until I'd decide to go back to Japan. The fix was rather simple, instead of signaling an error, it simply returns default timezone offset without considering old timezone offset. I think that's good enough. (NB: the timezone object would consider the when, means if you ask timezone offset of before 1835 in the Netherlands, then it would return GMT+0:19:32. No need for this? just for fun.)

The second one was rather stupid mistake. Again it was in Japan. I've found a tweet that said time-utc->date didn't consider timezone offset but just return UTC. I saw this when I fixed the first bug so I thought it might be related. Well, kinda but not quite. This bug happened only on Windows (including Cygwin) running on a timezone without summer time (Japan for example).

The reproducing was one easy step. Change system timezone to 'Osaka, Sapporo, Tokyo' then get local timezone. Aha, it returned UTC. But why? Well, very simple. To get local timezone name on Windows (and Cygwin), Sagittarius uses GetTimeZoneInformation and check the return code. If the return code was not TIME_ZONE_ID_UNKNOWN then it returns standard timezone name, otherwise UTC. Hey, MSDN says if the timezone doesn't have summer time then this return code would be returned! That's why if it's in Japan, it returned always UTC. Careless (or stupid) mistake.

Even though I'm using CI services for Linux, Windows and OS X, this type of physical location related bugs are really hard to find. (Not even sure if I can change system timezone per build on the services) I've just seen importance of feedback in a fresh light.

08 Oct 2015
typo fix. the light wasn't from jewel meat...

2015-09-29

暗号ライブラリ (別題:実用Scheme)

Schemeは黒板言語だと言われたりするのだが(概ね認める部分もあるが)、プログラミング言語は実用されないことにはコミュニティも広がらないだろうということで、完全R7RSのみで暗号ライブラリを作っていたりする。ちなみにR6RS処理系用はindustriaがあるので、そっちを使った方がよいと思われる。

ライブラリの名前はAeolus(アイオロス)。まぁ、そういうことです。基本的にはSagittariusで実装されてる(crypto)ライブラリに似せた感じのAPIにしてある。使い方は大体こんな感じ。
(import (scheme base)
        (aeolus cipher)
        (aeolus cipher aes)
        (aeolus modes ecb))

;; 128bit key
(define key (string->utf8 "1234567890123456"))
(define cipher (make-cipher AES key mode-ecb))

;; 16 octet block
(cipher-encrypt cipher (string->utf8 "It's top secret!"))
;; -> #vu8(230 1 210 64 10 131 72 18 222 112 210 129 170 236 243 42)
パディングとかはまだ実装してないので、自前でデータをブロック長にする必要があったりする。

以下はここにあるR7RS準拠の処理系での動作チェック。部分準拠のものは試してない。

完動(全テストパス)
  • Sagittarius 0.6.8
  • Gauche 0.9.5 (HEAD)
  • Larceny 0.98 (ただしパラメタのテストはtest-errorの実装がおかしいので動かない)
  • Chibi Scheme (23ac772e3a)
テスト失敗
  • Chibi Scheme 0.7.3 (AESのテストがこける。SRFI-33っぽい、使わないようにしたらテスト通った)
動かん
  • Foment (複数のバグを踏んだ)
  • Picrin (パスの通し方が分からん)
  • Kawa (同上)
未検証
  • Husk (Haskellいれるのだるい)
PicrinとKawaはなんとか試してみたいのだが、いかんせんライブラリパスの通し方が分からんので手が出せない。誰かテストしてくれないかな(チラ その他リストには載ってないけど動いたとかの報告があると嬉しいなぁ(チラ

とりあえずDES、Triple DESとAESをサポート(というか、当面はこれだけの予定。Blowfishとか欲しい人いる?) 以下は当面のTODO
  • パディング(パラメタにするか明示的にユーザにやらせるか悩み中)
  • ハッシュ(MD5、SHA-1、SHA-256、SHA-512等)
  • MAC(HMAC、CMAC辺り)
  • RSA
  • PKI(X.509証明書とか。ここまでやるとほぼSagittariusの焼き増しに・・・)
 これくらいあるとTLSとかSSHとか実装できそう。

なんでこんなの作ったのか?


上の方に書いたのと被るけど、○○がないからSchemeは使わない(使えない)と言われるのが嫌だったから。仕様内だとソケットやスレッドがないのでいろいろ厳しいんだけど、そこに依存しないピュアSchemeなライブラリを書いていけばそのうち人が増えるのではないかと。黒板言語と呼ばれる理由の一つに実用的なライブラリが圧倒的に足りないというのがあると思うので、そこを何とかしていけばいつかきっととか。以前書いたPostgreSQLバインディングもそんな気持ちからというのはある。(Scheme使ってPostgreSQL使ってるっていう人の方は少ない気がするので、ちとニッチ過ぎたというのはあるが・・・)

まぁ、後は仕事で暗号関係を使わなくなってきたので、忘れないようにというのもある。誰にも聞かれないと思うけど、一応動機。

2015年9月30日追記
Chibiのバグが直されたので完動に追加。仕事が速い。

2015-09-24

process-wait with timeout argument

Recently, I'm writing own CI task on my local machine. (it doesn't mean I quit others when it's completed but just for fun.) Then, I've noticed that it might be convenient to have timeout argument on process-wait instead of using timer to poll every 500 ms (or whatever). So I've implemented it, now you can use like this:
(import (rnrs) (sagittarius process))

(let ((p (call "sh" "sleep_forever.sh")))
  ;; wait for 5 seconds. can also be time object.
  (unless (process-wait p :timeout 5))
    ;; it returns #f if timed out. so kill it
    (process-kill p)))
Now, I don't have to make timer to check. Very convenient :)

TL;DR


From here is the description of underlying implementation. This is not something you may be interested in but simply for my memo (and hope that somebody would indicate better solusion).

Sagittarius supports both Windows and POSIX environment. On Windows, the story was very simple, I just needed to call WaitForSingleObject with process handle and timeout millisecond. Hurray done!. I like this abstraction that API can handle almost any kind of handle. (Most of the time it's a headache to support Windows but sometimes it's easier than POSIX.)

On POSIX, on the other hand, it doesn't have timedwaitpid or something like that. I've asked the teacher, Google, what would be the solution. The first hit was this: Waitpid equivalent with timeout?. Its best answer doesn't seem the best answer since entire process would be affected. Plus, it would always wait for specified timeout amount of time which is not something I want. The most useful pointed one looks nice if POSIX has a portable way to get standard output file descriptor from pid. Though, there seems a way to do it using ptrace(2). (See reptyr(1) and  its source). I haven't looked into its detail but, in my understanding, it opens given pid process with ptrace(2) and calls dup(2) on that process (ptrace_remote_syscall does this black magic I think). It'd be nice to have it if I can do this all platforms Sagittarius supports. However not an easy task to do it without having real environments (e.g. OS X is only on Travis CI).

Go easy


What I wanted to do is waitpid with timeout. So I just need to have a watch dog which alerts either timeout is happened or the target process is finished. Well, the easiest one I could think of was thread with pthread_cond_timedwait(2).

The idea is pretty much simple. It goes the following steps:
  1. Create a thread with the thread entry which calls waitpid
  2. Call pthread_cond_timedwait.
    1. If this return ETIMEDOUT, then send signal to the thread and return #f
    2. Otherwise return the return code.
Done! What an easy solution! (There was a stupid mistake. I didn't know pthread_join can't be called with detached thread. Though, interestingly, it worked on FreeBSD, why?)


Issue


Well, if I can say this is a perfect solution, I'd be super happy but of cource this has an issue (for now only one I'm facing!). Because of the limitation of waitpid (2), the pid can be waited must be created by the parent process means Sagittarius script. Thus processes created by pid->process can't be passed (well this is not only for timeout argument but entire procedure issue, though). If this happens, then ECHILD is raised (see waitpid(2)).

I haven't got any problem with it but if would, then I need a better solution (maybe set PPID to running process? but how?). But for now, I'm happy enough and I believe there's very few situation which users want to wait non child processes.

Again, this isn't an issue on Windows. I don't care good or not but I like it.

2015-09-22

SMTPクライアント

何かが失敗したときにメールを飛ばせると便利かなぁと思い書いた。こんな感じでメールが飛ばせる(サンプルはドキュメントから)。

(import (rnrs) (rfc client))

;; creates SMTP mail object
(define mail 
  (smtp:mail
   (smtp:from "Your name" "your-address@example.com")
   (smtp:subject "Subject")
   "Message"
   (smtp:to "recipient@example.com")))

;; creates an SMTP connection
(define smtp-conn (make-smtp-connection "your.smtp.server.com" "587"))

;; connect to the server
(smtp-connect! smtp-conn) ;; returns SMTP connection

;; Authenticate if required.
(when (smtp-authentication-required? smtp-conn)
  ;; NOTE: only AUTH PLAIN is supported for now
  (cond ((memq 'PLAIN (smtp-connection-authentication-methods smtp-conn))
         (smtp-authenticate! smtp-conn (smtp-plain-authentication
                                        "username"
                                        "password")))
        (else (smtp-disconnect! smtp-conn)
              (error #f "authentication method not supported" 
                     (smtp-connection-authentication-methods smtp-conn)))))

;; Send it
(smtp-send! smtp-conn mail) ;; returns SMTP connection

;; Clean up
(smtp-disconnect! smtp-conn)
メールを作る部分は利便性を高めるためにマクロを用意してて、これの嬉しい点としては、記述力が高いこともあるけど、以下のようにメールをテンプレートとして外部ファイルに書き出しておいて、readevalで手軽に作成することができることもある。
(define mail
  (eval (call-with-input-file "mail.scm" read)
        (environment '(rnrs) '(rfc smtp))))
今のところは考えてないけど、メールのソース(MIMEテキスト)からメールをパース・生成するというのがあってもいいかもしれない。(その前に認証をもう少しなんとかしないとという感じではあるのだが。PLAINだけとかいくらなんでもねぇ・・・)

 一応RFC5321に書いてあるコマンドは全部実装してあるが、拡張とかは全然だし、エラー処理とかもまだ大分甘いので使って直していくという感じ。

2015-09-11

call/ccで嵌った話

call/ccというよりはguardなんだけど。

エラー処理をしたいとか、エラーが起きても処理を継続したいという場合はままある。そういったときに使えるのはguardであることもまぁ周知の事実だと思う。これから提示する例も常識的に理解されているものかもしれない。

まずは以下の例を見てもらいたい。
(import (rnrs))
;; (import (scheme base) (scheme write))
;; (define mod modulo)

(define count 100000)

(define (run)
  (let loop ((i 0))
    (if (= i count)
        i
        (guard (e (else (loop (+ i 1))))
          (when (zero? (mod i 5))
            (error 'who "dummy"))
          (loop (+ i 1))))))

(display (run)) (newline)
(flush-output-port (current-output-port))
これをみて、「あぁ、これはまずいわ」と一目で分かったら以下を読む必要はないです。

これがまずいプログラムだということは既に書いているのでいいとして、何がまずいか。問題になるのはguard内で外側のloopを呼んでいること。一見すると問題ないように見えるのだが、多くの処理系でguardの実装にcall/ccを使用しているのが問題になる。実装例:SRFI-34
参照実装を展開して簡潔に書くと以下のようになる。
(define (run)
  (let loop ((i 0))
    (if (= i count)
        i
        ((call/cc (lambda (k)
                    (let-values ((args (loop (+ i 1))))
                      (k (lambda () (apply values args))))))))))
はい、末尾再帰じゃないですね。なのでスタックがあふれます・・・orz

実際のところとして、R6RS的には末尾再帰になることを要求しているので上記はスタックがあふれるとまずいのだが、(嘘ついた。<cond>を<body>と空目した。)これが問題なく動いたのは確認した中ではChezとRacketだけ。(GuileとVicareは試してない。) もちろん、この2つはスタックを拡張して動かしてるだけかもしれないけど・・・ちなみにR7RSは末尾再帰であることを要求していないので、上記は動かなくても問題ない。

この挙動で嵌ったの実は2回目で、3度目があると嫌だなぁと思ったので適当に書き記しておく。 しかし、どうやったら末尾再帰なguardが実装できるんだろう?参照実装では無理だよなぁ?

追記:
直した。https://bitbucket.org/ktakashi/sagittarius-scheme/commits/7bab13c1e83820eda28fc7878b14209fe1b87df3?at=default

追記の追記:
Shiroさんとのやり取りで上記の修正が正しいのか不安になってきた。っが、問題になるケースが思い浮ばない+スタック消費しないのでこのままで行くことにする。

Problem of hop on hop off projects

Hop on hop off projects is the term I made. This means you join a project in short term, then join other project in short term, like hop on hop off tour buses. (I just don't know any word describes such a style of driving project, drifting?)

I'm currently working with kind of scrum environment. Why kinda? It's because sprint period is rather longer than usual (4-5 weeks) and no standup meeting. The same part is that each sprint I get new task(s). By now, the tasks I've got assigned were not really related so each time I need to look into something I don't know (of course product specific thing). Thus hop on hop off projects.

It might be only me but if I don't have long term commitment of a project, then I lose interest and start writing crappy code. This is because I start thinking that "I would move to next something I don't know anyway why should I write maintanable code?". Probably, I don't feel any responsibility to the code I'll never see in future. (Plus, the current code base is really pile of shit, I don't want to swin into that. Too risky...)

What happen if I'm such a state? For example:
  • Start using copy&paste instead of extracting common use-case somewhere usable place.
  • Using magic number/string as everybody is doing.
  • No tests (well, I don't think there's a culture writing a test in this company...)
These are happening right now. Of cource I know I'm not doing right but risk is too high if I touch/refactor something without tests. I do what I suppose to do but I'm not those highly motivated people so I don't much care as long as I don't see it anymore.

The funny thing about this is that my company is actually developing one product however they don't assign to the same project (so far) or don't have long term assignment. Each task must be done at most a month. I understand that's the basic idea of scrum. But by now, I can only see the greate failure, such as:
  • Wrongly abstracted classes
  • No tests
  • Copy&pasted code
  • Only few people know the structure of code/architecture
  • No refactoring (of cource, there's no efficient tests!)
  • etc.
I'm such a lazy person so I'd write as maintanable as possible if I need to maintain the code. But if I don't have to, this laziness seems to take into horribly.
Or maybe I'm considered as one of useless developers so they don't want me to do anything but piling crap. That's fine by me, as long as they pay my salary.

2015-09-09

ハッシュテーブルSRFIs

ハッシュテーブルに関するSRFIが2つ提出された。一つはJohn Cowanの「SRFI-124: Intermediate hash tables」でこれは既存のSRFI-69の互換性を保ちつつ拡張するというもの。もう一つはTaylan Ulrich Bayırlı/Kammerの「SRFI-126: R6RS-based hashtables」でこれは名前からも分かるようにR6RSで標準化されたハッシュテーブルを拡張するもの。SRFI-126はweakハッシュテーブルを要求しているのでこちらを実装すればもう片方は実装可能という感じである。(bimapをどうするかとかはあるが、Schemeで実装してしまえばいいわけだし、気にしないことにする。所詮別の型だし。)

これだけなら特にネタにもならないのだが、現状SRFI-126はweakハッシュテーブルと通常のハッシュテーブルの操作を同一の手続きで行えることを要求している。インターフェースの統一という感じだし、実用を考えればわざわざ「weak-hashtable-ref」とか書かずに「hashtable-ref」でアクセスできた方が楽というのはあるだろう。問題はどうこれを実現するかということだ。普通に全ての手続きでハッシュテーブルのタイプを場合分けしてもいいんだけど、泥臭い上に拡張性が低い。別のハッシュテーブルが追加されるという可能性は低いといえば低いが、ないわけでもないだろう(concurrentハッシュテーブルとか)。とすると、もう少しマシな方法を考える必要がある。

現状Sagittariusはハッシュテーブルとweakハッシュテーブルは完全に別の型としているのだが、これを以下のようにするとなんとなく拡張性が高くなりそうな雰囲気がある(あくまで雰囲気)。
          +-----------+
          | hashtable |
          +-----+-----+
                |
      +----------+-----------+
      |                      |   
+-----+------------+ +-------+--------+
| normal hashtable | | weak hashtable |
+------------------+ +----------------+
まぁ、普通というか、ひねりも何にもなくインターフェースと実装を分けるだけという。実際にはこれにmutableとimmutableのクラスを追加してやろうかなぁとも考えている。こうしておけば後で意味不明なハッシュテーブルが現れてもそれなりに問題なく動くことが期待できそうだ。

このSRFIは出てきてまだ数日なので上記の変更を入れるかを決めるのは時期尚早な気がする。ただ、この変更自体はやってもいいかなぁとも思えるのでどうしようかなぁというところ。

2015-08-28

OS X support and Travis CI

Travis CI doesn't support Bitbucket so I didn't use it until now. I knew there's a way to use it, more precisely, there's a service which synchronises Bitbucket's repository to Github (BitSyncHub). But I didn't use it since there are couple of CI service which support Bitbucket (e.g. drone.io). Now, I've heard that Travis CI supports OSX so I wanted to use it. Using BitSyncHub wasn't difficult at all (so if you want to use Travis CI, it might be worth to consider). Enabling multiple OS support requires dropping a line to their support. No problem. Then I've got the environment, yahoo!!

OS X is, I believe, considered POSIX OS in most of the case. So I was hoping that Sagittarius would work without any change. Well, it didn't. When I write OS specific code, I refer POSIX spec to make sure I'm writing portable code. Was I doing right? I think so because the code worked on FreeBSD without any change which is also considered POSIX compliant OS. The pitfalls of OSX were the followings:
  • sem_timedwait is not implemented (linker error)
  • sem_init is not supported (can be compiled but an error)
  • Passing O_TRUNC to shm_open is an error.
Well, not that much things but pretty much annoying. Especially the first one. I've created a patch to make 0.6.7 be compiled so that CI server can build it.

Long time ago, Sagittarius got a pull request which made it work on OSX. The PR also contains a fix for libffi search path. It requires to specify the path explicitly. Which I think fine as long as you have control of the environment. However on CI server, we don't know until when the version is there. So I've written kind of solution to fine libffi in build process. So now, you can simply build like the following:
$ cmake .
$ make
It does kinda ugly thing internally but it's working so I'm happy with it.

Then I've experienced build failure number of times (including stupid mistake), finally got the successfull build.

Now, I can say Sagittarius supports OSX again.

2015-08-17

プログラミングにおける公私

駄文

高校で物理の教師が担任だったときに「数学に疲れたら国語を勉強して気分転換して、一日10時間勉強する」とか言われた記憶がある。勉強すること自体に疲れるのにどうやって別科目をやって気分転換するんだ?と疑問に思ったことがある。あれから15年ちょっとなんとなくあの教師の言っていたことが分かった気がする(遅い)。

僕の職業はプログラマで趣味(の一つ)もプログラミングである。職場で書くコードは大なり小なり制約があり思い通りに書くことはできない。言語の制約だったり(Java辛い)、積みあがった糞を崩したくないという精神的枷であったり、あんまり深く追求したくないという己の弱さだったりとまぁいろいろだ。例えば今の職場は、ユニットテストを書く習慣があんまりないかつテスト自体を書くのが驚くほど辛いので既存のコードを弄るのが怖いという個人的には致命的な枷があり、コードを書くのが辛いのである。(そんな環境を変えるという選択肢もあるかもしれないが、そこまで会社に思い入れはない+現状を変えたくないのに権力を持った人がいるので戦ってまで変える気もない。給料分だけ働きます状態。)

そんな状況でコードを書いているといろいろとストレスがたまる。特に現状を変えないように無理やりAPIに切り出す作業とか個人的に大分辛い。そうすると趣味で書いてるプログラムで思いっきり変更加えてストレスを発散しているのである。まさに「プログラミングでプログラミングの疲れを取る」という傍から見たら意味不明なことをしているわけだ。

プログラミングの一つの醍醐味として、自分の思ったとおりのプログラムを作ることができる(可能性がある)というのがあると思っていて、それは例えばパズルのピースがぴったりはまるような感覚で上手く抽象化できたとか、本来なら1000行くらい書く必要があるものを100行まで圧縮できたとか(マクロ中毒)、形は違えど思い通りになる感覚がいいのである。個人的にはこれが得られないとストレスになるらしく、どうしようもなくコピペが要るとか、あまりに酷いコードだけどテストがないから直せないとか、仕事で書くコードはそういったものが趣味で書くものより多いみたいである。

自分が書くコードがきれいとか上手いこといっているとは思わないし思えないが、それでも思い通りに書き換えることができる(もちろん動作は変えないで)というのはやはりストレスを発散することができるようである。特に不要なコードをばっさり削ったときの爽快感は一度味わうと止められない。趣味のプログラミングで気分転換をするときは何かしらがごそっと変わっている可能性がある。いいか悪いかは言及しないことにする。

取り留めなく終わり。

2015-08-14

Renaming identifier (solution of pandoric macro)

I've found a solution for the bug described on the article: pandoricマクロ. It was a rather simple solution.

There were 2 issues and one was a bug.
  • Making a global variable strips syntax information of the given identifier (bug)
  • Explicit renaming doesn't rename when identifiers are bound
The first one was a very simple bug, on the compiler if define has an identifier for its binding's name, then it shouldn't strip. That's it. Though, this isn't a good solution because if the identifier is bound in other library then the binding would be created not the one creating a binding but the one created the identifier. I think it's not a big deal but rather weird.

To resolve the weirdness, the identifier needs to be renamed. On Sagittarius, identifiers internally contain its identity which is a sort of history when the identifier is renamed. If the identity is #f, then it's a global identifier (means almost the same as raw symbol). Now, as far as I remember, each identifier, which reached to define and contains identity, are renamed means created in macros and it should be safe to change its name to unique symbol which is done by compiler via rename-pending-identifier. So I've added extra check to change the identifier name.

The benefit of this change is not only making R7RS syntax-rules work the same as R6RS one but also make R6RS datum->syntax works more R6RS compliant. More precisely, it resolved this issue. So now this won't work:
(import (rnrs))

(define-syntax define/datum->syntax
  (lambda (x)
    (define (concat n1 n2)
      (string->symbol
       (string-append (symbol->string (syntax->datum n1))
              "-"
              (symbol->string (syntax->datum n2)))))
    (syntax-case x ()
      ((_ name1 name2 var) ;; oops
       (with-syntax ((name (datum->syntax #'k (concat #'name1 #'name2))))
     #'(define name var))))))

(define/datum->syntax n1 n2 'bar)

n1-n2
;; -> error
(though, I've also found a piece of code depending on this bug...)

In my understanding, this type of renaming isn't required on R7RS. So this is a valid R7RS script:
(define-syntax defbar
  (syntax-rules ()
    ((_ name)
     (defbar name t1))
    ((_ name t1)
     (begin
       (define t1 'bar)
       (define (name) t1)))))

(defbar foo)

t1
;; may or may not an error
For example, Chicken Scheme returns bar. (For my preferecne, if identifiers are bound in macros, then it should be renamed as R6RS requires, but I can't do much about it.)

2015-08-10

手抜き力

最近日常的に割りと限界まで自分ができることを詰め込んでいるのではないかということに気づいたのと、それだとまずいなぁと思ったので自戒を込めたポエム。

一生懸命という言葉がある。元々は一所懸命という言葉だったのが、どこかで間違って一生懸命となったらしい(要出展)。僕は人生是すちゃらかをモットーにしているのだが、どうも何かを頼まれたりやろうと思ったりすると加減というものが効かない性分でもあるらしい。頼まれたら確実に不可能でない限り引き受けるだろうし、やると決めたら割ととことんやるので大抵どこかで息切れをする。これらのことが期限付きもしくはゴール付きのことであれば終わりがあるのである程度大丈夫なのだが、無期限もしくは終わりがないものだと問題になる。

例えば100m走を思い浮かべればどんなことかイメージしやすいだろう。100m走であれば、100m全力で走った後は失速しようが血を吐いて倒れようが目的は果たしたのでそれ以上に何かを求められることはない。それがマラソンだったらどうだろうか?100m走って止まってもまだ終わっていない。残り42.095km走らなければならないのだ。

話を一生懸命に戻してみよう。一生を懸命に生きる、すばらしい言葉だと思う。でも人生を80年と考えて常に全力疾走できるだろうか?残念ながら僕のような凡人には無理である。30数年生きたが24時間365日の内5割は手抜きして生きてきたと思う。それがここにきて手抜きの割合が多少減ってきたのである。別に大したことではない。例えば掃除を隅々までやるとか、毎日3食作るとか、そういった日常的なことの積み重ねで手を抜かなくなってきているのである。もちろん趣味の範囲とかもそれなりに拡大しているし、最近だと書類を集めるのに奔走したりとかいろいろある。

単に年を取って体力が衰えただけともいえるかもしれない。しかし、それであればより現状の自分の限界を確かに見極める必要がある。朝起きて、朝食作って掃除して買出ししてジムに行ったら15時くらいなんだけど、もう体力がないとかになってしまうと、何かあったときに全く動けない(割と切実)。

完全に自業自得なこと書いてるんだけど、ここ数週間ちょっといろいろあって上記の何かあった状態になっているのだが、ジムに行くのをキャンセルしても何かあったの何かが帳消しするぐらいに体力を持っていくので一つ一つのタスクを手抜きしないと倒れる状態になってたりする。しかも、この何かは無期限に続く系のものなのでふとこんなことを書いてたりする。若いのは精神年齢のみであるので肉体年齢相応にしないとという自戒。

2015-08-09

pandoricマクロ

SchemeでCLのpandoricマクロを実装したらSagittariusでは動かないというのを捕捉した。コードをGistに貼り付けてもらった。これ。正直見ただけで、「あ、これ動かないやつだ」分かるのが嫌だったが、一応確認してみた。うん、動かないね・・・

一応言い訳をしておくと、R6RS版のsyntax-rulesなら動く。問題になるのはR7RS版のsyntax-rules。何度もブログに書いてるから知ってる人は知ってると思うけど、SagittariusではR7RSで追加された拡張を実現するために、R7RSのsyntax-rulesはChibi Schemeから移植したものを使っている。これは大抵の場合で上手く動くんだけど、上記のような、テンプレート変数で生成した一時変数を別ライブラリで大域に束縛すると動かなくなる。

もう少し短い例だと以下のようなコード:
;; foo.scm
(define-library (foo)
  (export defbar)
  (import (scheme base))
  (begin
    (define-syntax defbar
      (syntax-rules ()
        ((_ name)
         (defbar name t1))
        ((_ name t1)
         (begin
           (define t1 'bar)
           (define (name) t1)))))))

(import (scheme base) (scheme write) (foo))

(defbar boo)

(display (boo)) (newline)
;; -> error
#|
sash -r7 foo.scm
|#
(scheme base)(rnrs)にすると動く(define-libraryは変更する必要はない)。何が問題かといえば、defbar内で細くされたテンプレート変数は、そのマクロが定義されたライブラリを内部で保持する識別子となるため、展開後に参照しようとするとそんなものないと怒られるのである。これは健全性を保持するためにそうなっているのだが、一時変数を大域で束縛するとそれがあだになるのである。

ではどうするかなのだが、一番確実なのはsyntax-caseで実装するというものなのだが、これも実は内部的な問題がある。コンパイラ内でマクロを使っているのだが、このマクロはerで実装されたsyntax-rulesであるということに大分依存している。単純にerの方が作りが単純なので識別子が保持する環境とかをあまり考えなくて済むというだけなのではあるが。さらに、これをやるとR6RSとR7RSで使用する_...を分けなければならなくなるのであまり美味しくない。(理由はsyntax-caseにある)

次にやれそうなのは、syntax-rulesの実装を変えることなのだが、これやってもerで作ったマクロに問題が残ることになるので、近い(遠いかも)将来、erがR7RS-largeに組み込まれた際にいやな感じになる。(のでやらない)

残るは少しadhocになるが、大域に束縛された識別子の定義位置が別ライブラリだった場合に同一の識別子の位置を無理やり束縛されるライブラリに変更するとかになる。ぱっと思いつくパターンでは動くような気がするんだけど、これだけadhocな変更だと大体どこかでほころびが出ることが過去の経験から分かっているのでやるなら思いつく限りのパターンをテストしないとという感じになる。(まぁ、似たようなことをsyntax-caseでやっているので動くとは思うんだけど、どうだろう?)

ちと考える必要があるなぁ・・・

2015-08-06

Safer thread termination (2)

I think I've found a (imperfect) solution to do it.

Goal


The goal is pretty simple. No crash, that's it. Optionally, releasing resource as much as possible. But the resource in this case is not about Scheme world or Sagittarius created, it's OS resource such as allocated stack or so.

The problem


Yes, it's the problem. The problem was sometimes it crashed with 0xC0000005 (access violation, SEGV in POSIX way). The termination process was described in previous article (Safer thread termination) . The cause, in short, was interrupting Eip or Rip may break call stack frame.

As my conclusion, if the Scheme process went into deep inside of C function call, then the program counter is overwritten, the call stack may get broke. So when the process tries to return from RaiseException however there is no place to return or returning invalid address. (This may not be true but seems like it.)

Comparing stack pointer was not enough


In previous article, I've written to do it. It does prevent the error when the thread has already returned from entry point however it didn't resolve returning from deep stack address. So I need to find one more thing.

The issue is breaking call stack. Means, if I can restore it until the thread entry function is called, then the call stack is not broken and can return properly.

jmp_buf?


If I need to restore the stack frame of certain point, then setjmp and longjmp seem the things I need to use, instead of calling RaiseException. So I've put setjmp before calling Scheme world process. Then the thread-terminate! interrupts the process to the C function which calls longjmp.

Not a perfect solution


Unfortunately, this isn't a perfect solution. It works most of the time and, I think, should be good enough (so far I don't get crash in my test case). However, the following code may not work:
(thread-terminate! (thread-start! (make-thread (lambda () #t))))
The problem of this piece of code is that the thread may not be terminated. If the thread couldn't reach the point where setjmp is called, then thread-terminate! would call longjmp without proper jmp_buf. Or the thread wouldn't be terminated if it didn't reach the internal thread entry point. Who writes this crap? Who knows.

This may not be a perfect solution but at least less possibility to get crashed. Thus it's safer than before. So, for now, I'm happy with it.

2015-08-04

Safer thread termination

Terminating a thread is a dangerous operation (AFAIK). So this shouldn't be done in general. However I've wrote the library (util concurrent) which uses thread-terminate! to finish tasks forcibly. As my understanding, as long as you free all resources held by the thread, terminating thread isn't that badly wrong. Well, if this was the conclusion, then I wouldn't write this. It actually works fine on POSIX environments I usually test, including Cygwin, however not working properly on Windows.

Windows has the API which terminates a thread, called TerminateThread. I, however, don't use this because of the following reasons:
  • It may not release all resources
  • There is no way to handle after termination
If the resource aren't released, then it may leak eventually. I don't use Sagittarius on 24/7 service so this might be a trivial issue but you'll never know. So it's better to have as safe as possible.

If you don't use TerminateThread, then there's, afaik, not many choice to do it. The way I've chosen is using CONTEXT. The basic process is the followings:
  1. Suspend the target thread
  2. Check if it's active
  3. Get thread context
  4. Set program counter to the function calls RaiseException
  5. Resume the thread
The thread caller wraps the thread function with _try and _except, so the thrown exception will be caught.

Until here, there seems nothing wrong and works fine. Well no. This works most of the case however at some point you may get a context which contains no call frame of thread caller function. I think this means either thread is almost terminating or it's finished but still active. Then you'd get access violation error.

Now, what can I do? I think I'll try to compare stack pointer. Luckly, Boehm GC has base stack pointer on each thread. So if I can get this and compare with the thread context stack pointer, I might be able to detect if the thread is already finished (or at least returned from the thread function of Sagittarius) or not.

If you know better way, please let me know.