タグ別アーカイブ: プログラミング

C + Tcl/TkでHello, World!

Tcl/TkはCやC++のプログラムにちょっとしたGUIを付けるのに便利です。Tcl/Tkはスクリプト言語であって、ライブラリとして使えることを知らない人も多いようですので、今回はCからTcl/Tkを呼び出してHello, World!をウィンドウで表示するプログラムを紹介することにします。

CからTcl/Tkを使うには、当然のことですが、Tcl/Tkがインストールされていなければなりません。Windowsであれば、Cygwinなら標準パッケージに含まれていますので、setup時にTcl/Tkを一緒にインストールすればOKです。なお、Cygwinの場合はX Wndow Serverを起動しておく必要があります。MinGWでも、Tcl/TkがMinGW本体と同じところからダウンロードできるはずですので、それをインストールしましょう。Visual C++を使うのであれば、Active Tclをダウンロードしてください。

Linuxであれば、はじめからインストールされている場合もありますし、なければapt-getやyumなどでインストールしましょう。Macの場合はMac Portsを使えばよいでしょう。もちろん、LinuxでもMacでも、ソースからコンパイルしてインストールすることもできます。

続きを読む

改めて感じるTcl/Tkの素晴らしさ

Tcl/Tkというと、何とも古臭いもののように感じる方も少なくないことでしょう。あるいは、「何それ?」ということで、聞いたこともない方もいるかもしれません。

Tcl/Tkというのは、スクリプト言語であるTcl (= Tool Command Language) と、そのライブラリである Tk (= Tool Kit) をあわせた呼び方です。TkはGUIツールキットとして非常によくできており、Tcl以外からも使えるようにさまざまな言語にバインディングされています。たとえば、Perl/Tk、Ruby/Tk、PHP/Tk、Tkinter (Pythonへのバインディング)などがあります。

かなり古くからあるものですので、古臭く感じるのはある意味仕方がありません。とはいえ、Tclが生まれたのは1988年、Tkが生まれたのは1990年代に入ってからです。CのANSI規格が制定されたのが1989年、Javaが登場したのが1990年代前半ですから、とんでもなく古いわけではありません。

続きを読む

JavaでトレースログのON/OFFをコンパイル時に切り替える。

JavaでAndroidのプログラミングに関わるようになってしばらく経ちますが、そろそろトレースログのON/OFFを上手く切り替える方法が欲しくなってくるものです。ベテランのAndroidプログラマーの方に聞いたところ、if文の条件式に定数(static finalで宣言したboolean型のフィールド)を指定することでON/OFFを切り替えるのが普通だといいます。

その方法は、私なりに以下のように解釈しました。

static final boolean ENABLE_LOGS = true;

if (ENABLE_LOGS) Log.v(“tag”, “message”);

見た目はともかく、これならログを無効にしたときには、実行時のコストが完全になくなりそうです。ただ、ON/OFFを切り替えるにはソースファイルをその都度修正する必要があり、これはいただけません。

続きを読む

Javaの設計思想が少し見えてきました。

Java のコードを本格的に書き始めてまだ数日ですが、少しずつ Java の設計思想が見えてきたような気がします。

以前は一貫性のないメソッドやコレクションや配列の間の変換のやりにくさに辟易していましたが、今では、「まあこういうのもありかな」ぐらいに感じています。

結局、目的に応じて配列やコレクションの類いは使い分ける必要があるわけで、場当たり的に選択するのではなく、よく考えて適切なものを選択し、自分のコードの中で一貫性を持たせていれば大きな問題はおきないようです。

Integer などの Number から派生したクラスが、内部の状態を更新できないのは参りますが、マルチスレッドのこととか考えるとこのほうがよいのかもしれませんね。

少し、Java のことを見直しました。

らしくない。

リニューアル後のブログの記事を見たところ、Java や Android の記事はあっても C や C++ の記事がありません。以前のブログであれば、Java や Android の記事はまったくなかったので大違いです。

我ながら「らしくない」というのが率直な感想です。今後も Java や Android の記事は書いていくつもりですが、C や C++ の記事がないのは一過性のものですので、そちらを期待して来られた方はもうしばらくお待ちください。

Javaプログラマーが知らないJava言語仕様

実際のところどうなのかはわかりませんが、Java に関してタイトルのような状況があるとかないとか。以下、その内容を具体的に書いていきます。

  • ビット演算やシフト演算は C ならできるけれど Java ではできない。
  • 同じファイルの中でクラスを複数定義できない。
  • クラスに属さない列挙型は定義できない。

これらはすべて間違いなのですが、迷信的なことがまかり通っているようなのです。上記はすべて Java でできることばかりです。

少し補足すると、同じファイルの中では、public なクラスはひとつしか定義できないのであって、public ではないクラスであればいくらでも定義することができます。

列挙型は一種のクラスのようなものなのでしょうね。どのクラスにも属さない列挙型を定義できますし、結果として列挙型の定義のみを含むファイルというのもありです。

お行事のよさが好きになれない

先日から Java についての調査を始めたことを書いています。その中で感じるのは、Java というプログラミング言語の設計思想は、C や C++ とはまったく違うということです。C# なんかと比べてもやはり違います。

何が違うかというと、ひとことでいうなら、その「お行儀のよさ」です。お行儀がよいのは悪いことではありません。しかし、ときには泥臭いことに手を染めなければならないこともあるのです。そんな状況では Java お行儀のよさはデメリットにしかならないことがあります。

例えば、Java ではメソッドの結果は必ず返却値で返すことを前提としていることがあります。実際には、引数で渡したインスタンスを更新することはできますが、では int 型などのプリミティブな型の引数を更新して呼び出し側に結果を返せるかというと、それはできません。インスタンスそのものを再割り付けした結果を返すこともできません。

これが C や C++ であればポインタを使えば簡単に実現できます。C++ なら参照を使ってもよいでしょう。C# なら out を使えばやはり簡単に実現できます。ところが、Java にはそういった手段がないようなのです。

確かに、メソッドの入力を引数に集約し、出力を返却値に集約するのは正しいことです。しかし、その方法では無駄に動的なメモリ割り付けを行うことを避けられなくなります。私の目下の関心はパフォーマンスの改善にありますから、これは大問題です。

このようなお行儀のよさが随所に見られます。これは、C が「プログラマーは間違うことがないので信用する」ことを前提としているのに対し、Java が「プログラマーは馬鹿で間違いばかり犯すので信用しない」ことを前提にしているからでしょう。

パフォーマンスがそれほど大きな問題でないならそれでもよいのです。しかし、もしそうであれば私が重い腰を上げて Java に関わることなどなかったでしょう。現実には、パフォーマンスを改善するためにあらゆる手を尽くす必要がありますし、そのたびに Java の余計なお世話が行く手を阻むのです。

 

Javaについて調査中

Android アプリの開発に携わることになった関係上、Java についていろいろ調べています。大まかなことは以前から知ってはいたのですが、本格的に調べていくといろいろなことがわかってくるものです。

今後は、Java について調査したり実験した結果を自分自身の備忘録をかねて投稿していくことにします。ですので、ベテランの Java プログラマーの方々にとっては目新しい情報はないかもしれません。

現在は、Java でいかに高速なコードを書くかについて調査を行っています。というのも、現在関わっているプロジェクトが、パフォーマンスに関してかなりシビアだからです。Android ですが、実行速度がかなり要求されます。

おおざっぱに調べた感じでは…

  • Java コンパイラの静的な最適化はほとんど期待できない。
  • メソッドをインライン置換するには、private, final, static のいずれかにする。
  • 配列の範囲チェックなど、ランタイムチェックが大きなコストを払っている。

といったところでしょうか。もちろん、インスタンス生成のコストなど、Java に限らずどんな言語でも問題になる部分は上記には含んでいません。

JIT を初めとした VM の高速化についてはいろいろ語られているようですが、静的な最適化については意外に軽視されているのではないかという感が否めません。それならしそれで、腕の見せ所がいろいろあるわけで、私としてはある意味歓迎ではあるのですが。

ライブラリはアプリケーションの延長では開発できない。

アプリケーションの開発者というのはよく見かけますが、分野を問わず、ライブラリの開発者というのを見かけることはあまりありません。ライブラリを専門的に開発しているのではなくても、アプリケーションだけではなく本格的なライブラリを開発できるというプログラマーが少ないのです。

アプリケーションばかり開発しているプログラマーはこのようにいいます。「アプリ開発の過程で生まれたクラスやモジュールなどを再利用できるようにとっておきます」と。けれども、アプリケーション開発の副産物として生まれたコード群と、はじめからライブラリにすることを目的に作られたコード群では明らかな違いがあります。

はじめからライブラリにすることを目的に作られたコードは、汎用性や移植性、サイズ効率や速度効率などに相応の配慮が行われているものです。特定のアプリケーションで使うことに特化すれば、その目的に合致する限りは、もっと使いやすく、もっと効率的なものができるかもしれませんが、通常ライブラリはそのような選択はせず、もっと応用範囲を広げる努力をするものです。

きれいごとをいうのはやめて、もっと現実に目を向けるならば、アプリケーションの副産物として生まれたコードは細かいところまで作り込まれていないケースがほとんどです。

具体的にいうと、Java のクラスであれば、hashCode や toString といったメソッドを、それが生まれたアプリケーションで実際に必要となる場合以外にきちんと実装されているケースが果たしてどれだけあるでしょうか?

C++ であれば、アプリケーション独自のコンテナを作ったとして、それが本当に標準規格で定められたコンテナの要件を完全に満たしていることがどれだけあるでしょうか?

一点一点を指摘されれば、アプリケーション・プログラマーであってもそれらに対応できる可能性は十分あります。けれども、指摘される前から網羅的に必要なことに配慮することはまずできないのではないかと思います。

日本のプログラマーは、もっとライブラリを書く力を身につけてもよいのではないかと感じています。細かいところまで配慮したライブラリを書くのは、特定の目的だけを達成できればよいアプリケーション視点からは無駄のように見えることもあるかもしれません。しかし、一見遠回りのようであっても、実は近道だということはあるのです。