LoginSignup
2
1

More than 5 years have passed since last update.

Objective-C その可能性の中心を,WinObjCとNimで...探りはじめる。 (「IoTフロントエンド開発」シリーズ ③)

Last updated at Posted at 2016-12-22


実際のコーディングに関することは、以下に随時更新形式で書いていきます。
http://qiita.com/kmry2045/items/2cc138f58018a68db737

前文

俗に言う、「やってしまった」状態である。

iPhone登場とともにバズってしまったため、ブログ界隈では、やたらとネタ的にdisられるようになったObjective-C。disられる理由も分かりはする(あえて、書かない)。しかし,Objective-CはMac/iOSという一時代を築いたbetter-Cな言語という事実があり、また、実務で淡々とObjective-Cで書かれたコードをメンテしている方々がおられるのも,また事実。

それ,Swift4.0かSwift5.0で...的な話は機会があれば書くとして、1マカーとして割合とObjective-Cの恩恵に預かっている身として、Objective-Cコードをメンテしている方々の5年後・10年後の一選択肢として、Objective-Cにコンパイル可能なシステム開発言語にして、Smalltalkテイストなコードも組み込めるNimをオススメしようとしたところ,夜な夜な試すうちにはや10日が過ぎてしまった。

そう、故スティーブ・ジョブズのApple復帰の最初の支援者にしてリトルブラザーなビルゲイツの末裔どもがwindows UWP普及のために書いているWinObj-Cと格闘してしまったために....はい、Windows10 64bitをクリーンインストールして、WinObj-Cを夜な夜な動かしましたよ,睡眠時間削って。。あと何か月かすれば、まともなエントリーが書けるかもしれない。

本駄スレを読み流していただきたい想定読者を3行で。

  • iOS開発などで、Objective-Cを実務でたんたんと使い続けてきた方、もしくは、Swiftのメジャーバージョンアップに一抹の不安を感じている方(Swiftやめろとかいう意図はまったくない)。
  • マイクロソフトのユニバーサルWindowsプラットフォーム(UWP)で、モバイルもIoTも、とかいう話に困惑している方。WinObjCという単語が初耳の方。
  • 軽量言語テイストで、Null安全なシステム開発言語Nimに興味がある方。

ということで、iOSとWindows UWPの断絶を,Objective-CとNimで乗り越えてみせませう、
という妄想の2016年末の中間記録を以下に記す。
現時点で日本語情報がほとんどないWinObjC+Nimは大きすぎるテーマだが、
2017年か2018年に顛末記をいずれ書く。
その際にUWPがIoTでどの程度有用かも、中立、というより、マカーな視点でいずれ書く。

以下、いろいろ書く(カオス注意)。NimでのObj-Cブリッジ実行例は過ぎ去ってしまったNimアドベントカレンダーへのエントリーにいずれ追記する。

なお、当方Windows UWPを理解できていないので、UWPを実務で使っているような方、 もしお時間の余裕あれば、有用なリンクを紹介してくださいませ。

何の可能性の中心のネタなのか。

AIとIoTが話題となり続けるであろう2010年台後半、なりふりかわまないようになってきたマイクロソフトも、成長の壁についにぶつかった感のあるアップルも、けっこう悩ましいよね、というところが背景。コーディング視点では、十分な歴史がありXamarinが新たな居場所を提供してくれはじめたC#はさておき、いまだにほぼiOS向け言語なswiftのエコシステムが充実するのは、まだ先のことだよねー、といったあたり。
今回のネタは、Raspberry piくらいのスペックの機器を使ったIoTマイコン向け開発は、ちょっとした工夫で、マイクロソフトな実行環境UWPにおいてアップル言語Objective-Cを使って、快適に行えるようになるかも、という話。Swift3.0への追従で苦労されている方々はうなずかれるであろう理由により、こうした分野ではSwiftが入ってくることは当面ない。IoT開発の当面の主役は、組込機器開発の主要言語であるC(とアセンブラ)なのだから。

なんのことか意味不明な人は、以下の画像をクリックして、まずは、マイクロソフト社が、『おれたちの考えたさいきょうのクロスプラットフォーム開発環境』を、どや顔で(?)、爽やかにPRするビデオを見ておこう。
winobjc.PNG
出典 https://developer.microsoft.com/ja-jp/windows/bridges/ios

Visual Studioでobjective-c開発ができる時代なんだ(...iOSコードからインポートはできるが新規開発ができないっぽいが...)。
  

disり尽くされたSmalltalkテイストなC言語,Objective-c

NeXT,Mac OS 10, iOSといったOSや,iTunes/Safariなどの有名アプリを開発してきた栄光の歴史を持つ言語、Objective-c。だが、近年のアドベントカレンダーでの位置づけは、半ばネタ的なのか、完全にネタなのばっかり。C言語に動的なオブジェクト指向を組み合わせて大規模開発の生産性を向上に、といったObjective-cの20世紀末の立ち位置に歴史的意義があったことは、誰も否定しないところだろうけど、Cの構文中に、[dictionary[key] isKindOfClass:[NSString class]]といった大括弧がバンバン登場するあたり、生理的嫌悪感を覚えた方々が多々いたものと思われる。特にphpやrubyなんかのスクリプト言語をいじってきた方々には。

もちろん、Objective-cの枠内で生産性を向上しようという試みはあり、
たとえば、

objdict.m
NSDictionary *dictionary = @{
  @"en": @"Hello world!",
  @"sv": @"Hej världen!",
  @"de": @"Hallo Welt!",
  @"ja": [NSNull null] 
};

NSMutableArray *temp = [NSMutableArray array];

for (NSString *key in dictionary.allKeys) {
    if ([dictionary[key] isKindOfClass:[NSString class]]) {
        [temp addObject:[dictionary[key] capitalizedString]];
    }
}

NSArray *capitalized = [NSArray arrayWithArray:temp];

といった大括弧だらけな記述を、

notjs.m
    _.dict(dictionary)
    .values
    .filter(Underscore.isString)
    .map(^NSString *(NSString *string) {
        return [string capitalizedString];
    })
    .unwrap;

といったunderscore.jsライクな記述に変えられるライブラリも存在する。

とはいえ、さまざまな黒魔術が多々あるらしく、Swiftの登場によってObjective-Cから「卒業」した方々からは、完全に変態言語扱いである。他方で、大括弧記述の源流となったSmalltalk界隈の方々にすると、「あんなのはSmalltalkじゃねぇ」といった風らしく、村の変わり者扱い模様。。

Python風にも(Smalltalk風にも)記述できる新言語Nim

本エントリーはNimアドベントカレンダーの一貫で、本題は、python的な記法で低レベルの開発が行える言語NimをObjective-Cと格闘している方々、格闘したことがある方々に軽く紹介することだ。
そうした意図の下,ネタ探しにNimの近況を調べるうちに、意外な方面の方々がNimを話題としていることを知った。

SmalltalkerによるNim&Spry解説は、Nim使いを目指す上で興味深い。

Spryの大括弧なコード例。

1 to: 5 do: [echo :x]

Spry言語サイト。
http://sprylang.org/

こうした新言語をNim上でしごく短いコードで実現しているのだからNimのコード嫁というわけだ。
非力な私は嫁に行くことは現時点でできなかったが、Nim+Spryという構成を採用すれば、NimとしてPython風にも,SpryとしてSmalltalk風にも記述できる言語環境ができることは理解した。

そして、NimもSpryもC/C++に加え,Objective-Cのソースコードにコンパイルできる。すなわち、Nim+Spryは、Objective-Cの後継者候補と言うことができよう(->無理やり)。

少なくとも、Objective-Cを実務で使っている方は、ほぼ間違いなくスキルをお持ちの方と思われるので、今後もC系言語でシステム開発を続けていくためにも、バージョン1.0が迫るNimを一度見ておいてよいと考える(C++11/14/17を併用していくからobjective-c++で無問題という強者は除く)。

ということで、Objective-CとNimを並行して学んでいくことだってあり。

世間のObjective-Cのイメージは、Smallで動的で素敵な男の子(スプレイたん)を前に大変なことになっている変態さん、なのかもしれない...!?
[winobjc.PNG]

だが、そんなSpryたんが現巨人であるObjective-Cの肩の上に乗っかり,新時代の巨人の一人になって進撃していくことだってありうるのがIT業界。少なくとも,ここ3年でiOS/Objective-Cの肩の上に乗っかろうとする輩は、マイクロソフトをはじめ、ちょろちょろと存在する。android上に登場するのはひょっとするとFoundationCore+swiftベースのソリューションなのかもしれないが、その際は、SwiftだってObjective-Cの遺産なくしては誕生しなかったと言い切り、淡々とSwiftをやっていけばよい。
Swiftはいずれかのタイミングでキャッチアップすべきなのは当然として、Objective-Cをたしなんでおくことで広がりが出る。少なくともここ数年の間は、Swiftが組み込み機器開発のメインストリームになるとは思い難い。C言語そのものである2つの言語Objective-CとNimを併用し、伝統(コード資産)と生産性(モダンなコーディング)の両方を享受しようという、アプローチは、ありうる。
2~3年先には、実務ででも。

....以下、このことをお試ししようとしたせいで、普通だった俺が大変になった顛末記を書いて終わる。遺憾ながら。Objective-Cで実務こなしている方々ならば、その気になれば、Nimは全然余裕ですよ、たぶん。

顛末記① コンパイラの最適化動向から見たnull安全

Ojbective-Cな方々向けのメモ書きを以下に付記しておく。漠然と思っていたことをC++界隈からわかりやすく書いてくださった、「コンパイラが斜め上の最適化をするのが当たり前になりつつあるから,null安全ないと怖いよね」な、null安全に関するエントリー

コンパイラの最適化により効率的なコードを吐き出すことは、例えば、組込界隈においては、バッテリーの持ちを少しでも良くするために必要とされているのだろう。一方で、最近の「なんかいろいろIoT」なトレンドにおいて、組込機器のコードにまつわる脆弱性が、しばしば、null検査例外と関わっているのも事実だろう。

そこでnull安全な言語なわけですよ、と言っておいまいにしてしまえば話が早いのだが、実際に、null安全な言語が組込/IoT界隈に普及するにはハードルがある。後発のnull安全を目指す言語は、実行効率と安全なコーディングの間のトレードオフのさなかにあるのだから。

既に昨年にバージョン1.0に達しているrustは、このあたり、それなりの解を見出しているのだろう。1.0が近づいているNimについては、このあたり、まさしく現在進行系。そのあたりの取り組みをNimの非公式FAQからメモ書き的に翻訳しておこうと思った次第。

非公式FAQ Nimは安全なのか?(安全ではないのでは?)

Is Nim unsafe? の斜め読み記録。

これは、Nimがnull pointerの内容を参照できること、CのIRを扱えることから、しばしば発せられる問いである。手書きされたCのコードが引き起こしうるのと同様に、定義されない振る舞いを引き起こしてしまうCのIRをNimは扱える。

Usually this comes from Nim's ability to dereference null pointers and it's deal with compiling to C IR. Nim strives to generate C IR that won't cause undefined behavior as easy as how it can be caused by hand written C code.

しかし、Nimで書かれるコードが、null参照のような誤りを含んでしまうことについては、それを避けるいくつかの方法がある。

But when there is hand-written Nim code that contains errors like dereferencing a null pointer, there are ways to avoid this:

  • 非nilアノテーション (not nil Annotation):
    • このアノテーションは、nil(null)となる可能性のあるコードに適用できる。

You can use this annotation on any nilable type in your code and the compiler statically checks at compile time that your code can't possibly have a null pointer for that var
- Compiler flags:
- you can pass flags like -fsanitize, or -fsanitize=null for nil checks, which provide minimal overhead.
- In the near future, -nilChecks:On|Off will be available for explicit nil checking and instead of Segmentation Faults, when a null pointer is dereferenced, it will be a NilError Exception
- Also in the near future, -d:safety will be available to use along with -d:release for performance and safety (see: #2809)
- -d:release config
- by default, -d:release turns safety checks off, but if you configure config/nim.cfg, you can allow the checks you want enabled when invoking -d:release
- Thread Safety
- shared memory via lockable heaps is a feature Nim seems will implement soon.

You should also keep in mind these 5 points:
1. It's not a problem in practice in the real world, where people have access to a very good debug mode that catches all sorts of things at compile-time and at run-time.
2. It's not a problem with the right C compiler configurations.
3. It's not hard to "fix" this issue anyway. Where "fixing" means "pretending Nim created Ansi C code in the first place" (which it doesn't).
4. It's furthermore entirely deterministic in debug mode. It's nothing like a data race which you can never effectively test against.
5. Nim already encourages you to give the type a name and then 'not nil' can be part of the type definition easily

力尽きた。ごめん、えいごで読んで。。

言いたいことは、Nimが、名前空間すらないCの薄いラッパーであるObjective-Cに、型安全なコーディングの世界をもらたす可能性があるということ。
言うだけでは説得力がなく申し訳ないので、いずれコード例を示す。

Winobj-C格闘記

Nimと関係なく、ほぼここだけで日時が過ぎていったのだが、マイクロソフトの個々のダメダメはさておき、割合とおもしろかったので、格闘記を示す。追体験しようとする人に書いておくと、快適に追体験できる条件は、64bit版のOSでVitrtualbox等を動かしている人で、Vitrtualbox等に5GB程度以上のRAMを割く余裕があるマシンを使っていること。x-codeとの連携があるので、たぶんMac環境上で動かすのが良いのだが、自分はwindows10 64bit上でチャレンジした。

iOS 用 Windows ブリッジ(winobj-C)の導入

winobj-Cに関する唯一の日本語公式情報の以下から、評価用の仮想マシン環境をダウンロードする(容量は30Gb弱,英語版windows10、評価期間1か月)
https://developer.microsoft.com/ja-jp/windows/bridges/ios

実行後、「Win+I」キーを押下し、以下のような情報に従い、仮想マシン環境を軽量化する。
https://i-bitzedge.com/tips/how-to-super-speed-up-windows-10#2
仮想マシンの場合、グラフィック周りが弱いので、そのあたりの無駄な装飾を外すと快適に動作する。

開発評価用の仮想マシン環境のくせに、アメリカ人向けなゲームとかが無駄にプリインストールされているので、無言で、powershellを管理者権限で立ち上げ、以下のコマンドなどを実行する。

Get-AppxPackage *communi* | Remove-AppxPackage
Get-AppxPackage *xbox* | Remove-AppxPackage
Get-AppxPackage *bing* | Remove-AppxPackage
Get-AppxPackage *zune* | Remove-AppxPackage

これらの対策をしないと、virtualboxがフリーズしたりするので要注意。マイクロソフトのお作法なので、心を鋼鉄にして、淡々と実行する。

visual studioでobjective-c

長文書いて、力尽きたのでキャプチャだけ。

Capture.PNG

コンパイル速度と実行速度は想像の範囲内。UWPが言うがごとく、IoT環境で実行できるポテンシャルが本当にあるかどうかはさておき、VM上のwindows10環境では、各種グラフィックが意図通りには動いていないようだった。このあたりは、1年か2年先にはなんとかなると期待しておこう。Objective-C++の事例であるGLKit(OpenGLラッパー)を使ったデモは普通に動作した。

おまけ。Bash on Windowsも入っている。

VMはwindows10 開発者モード上のものなのでBash on Windowsも入っている。
まだの方はちょっと試してみるのもいいかも。

イランという人は、コマンドプロンプトから
lxrun /uninstall /full /y
で完全にアンインストールできる。

また使いたいと思った時には、コマンドプロンプト上でbashと打つだけでよいはず。

キャプチャ3.PNG

はぁ、はぁ...

ほんとはNimとobjective-Cの組み合わせは楽しくて大変なんだ。ただ、
本一冊が必要になるくらいの事前知識と準備作業が必要なのかも。

息切れが終わったのちに、その可能性の中心を書きたい。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1