2014年6月14日土曜日

Swift の第一印象とよいと思う点

新しいプログラミング言語かぁと、少し穿ちながら見ていたわけですが、
Swift についていろいろ情報を見ていくうちに触ってみたいな!と思いました。

とりあえず、Appleが提供してくれている以下の電子書籍を少しずつ読んでます。

The Swift Programming Language (iBook store)


ようやく4割弱くらいかな、前半読んでみて思ったことを少し書いてみます。

まず、何よりも感じたこと。それは、、

間違えやすい書き方を減らそうとしている


CやC++をよく使ってプログラムを書くのですが、これって間違えやすいよなぁと思う点がいくつかある。

1.とにかく型安全


コンパイラが必ず型チェックを行う。以下のは、まぁ普通にできないと思うけど。

let a : String = "1.5"
let b : Int = 2

var x = a + b // コンパイルエラー

一方で、あきらかに確定できる型に対しては、積極的に暗黙に型推定を行っている。
慣れればかなり書きやすいのではないかな。

2.行末の";"がいらない


いらんやろ、と思った人が何人いるか、という行末の";"。改行コードでちゃんと切り分けられる。
もちろん一行に複数行書く場合はちゃんと";"を入れて書ける。

let a = 1.5  // ";"がいらない
let b = 1; let c = 2

3.大きな数字の桁が分かりやすいように"_"で桁割ができる


これも小さなところだけど、大きな特徴。
定数なんか見直したりしないから、打ち間違えていたらなかなか気づかない。

let MILLION = 1_000_000

4.複数行コメントがネストできる


複数行コメントアウトを、さらにそれを包含して複数行コメントアウトできるようになった。
これも以前思ったんだよね、なんでできないの?!て。
こういうところ、うれしい。

/*
    let a = 10
    /*  let b = 20 */
    let c = 30
*/

5.switchが拡張


caseの条件が一致したところだけ実行(最終行に明示的なbreakがいらない!)。
C/C++の場合はcase文が終わっても実行が次のcase文に突入していってしまう。

var x = 3
switch x {
    case 0:
        println('zero.')
    case 1:
        println('one.')
    case 2:
        println('two.')
    default:
        println('many!')
}

また、caseに複数条件書けるようになった。関数化しておけばよいが、短いコードの場合面倒なので便利。

var x = 3
switch x {
    case 0, 1, 2:
        println('less than 3.')
    case 3:
        println('equal to 3.')
    case 4, 5, 6:
        println('more than 3.')
    default:
        println('many!')
}

caseの条件を数式で書けるようにwhere句が追加された。

var x = 2
switch x {
    case let a where a % 2 == 0:
        println('even.')
    case let a where a % 2 == 1:
        println('odd.')
}


てところで、長くなってきたので、ひとまず、続く!

2014年6月8日日曜日

新入りSwift、勉強中

開発環境を手に入れるには開発者登録しなくちゃいけないのだけど、
まずは手に入る情報から勉強。




かなり変わった印象なのでポイントを押さえないとね。

2014年6月3日火曜日

iOS8と新入りSwift

昨日、、というよりは今朝かな、アップルのいつもの催しがありました。

WWDC 2014。

とはいえ、一度もリアルタイムで見たことないのですが。
新しもの好きの血が騒ぎました。

アップル、新プログラミング言語Swiftを発表。レガシーを廃して高速化したiOS/OS X開発用

そう、iOS8が出るのは、まぁさておき。
新しいプログラミング言語!

Swift!

swift: definition of swift in Oxford dictionary

すばやく、みたいな意味かな。
会社の同僚曰く、pythonみたいなスクリプト系の言語らしいよ?
とのこと。

まぁとにかくです、いまがチャンスじゃないか?と思っている訳です。
新しいことには先にたどり着いた人が有利なのです。

さて、どうしたものか?

2014年6月1日日曜日

makefile、それは避けて通れない道

気づけば、また日にちがあいてしまった。。
技術系ブログなのだから、もっと頻度を上げたいんだけどなぁ。

ということは、さておき。


オープン系、とくにC/C++を扱っていると必ずmakefileと対峙するときがある。

今回はそんなお話。

久々にmakefileをいじって、効率よくコンパイルできるようにしようとしたのだけれど。
makefile内で設定した変数がいつ値がセットされるのか?をよくよく考える必要があるよ、ということです。

背景ですが、複数の異なるプロセッサに対して、同じソースでそれぞれで動作するバイナリを作成したい、そんなときにハマりました。

以下、はまったときのmakefile
projA: PRJ_SUFFIX=_A
projA: proj

projB: PRJ_SUFFIX=_B
projB: proj

OBJDIR=obj$(PRJ_SUFFIX)
BINDIR=bin$(PRJ_SUFFIX)
SRCS=main.c tool.c
OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
CFLAGS=-D__DEF$(PRJ_SUFFIX)__

proj: $(BINDIR)/proj

$(BINDIR)/proj: $(OBJS)
    @if [ ! -e $(BINDIR) ]; then mkdir -p $(BINDIR);fi
    gcc -o $@ $(OBJS)

$(OBJS): $(OBJDIR)/%.o: %.c
    @if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR);fi
    gcc -o $@ $(CFLAGS) -c $<

projAのときはprojA用のdefineを定義し、projBのときはprojB用のdefineを定義することで、プロセッサ個別のソースをコンパイルする、という流れです。

何が問題か?というと、ターゲットごとに設定した変数の値がmakefile内ですべてに適用される訳ではない、ということ。

具体的にみていくと、まずターゲット特有の変数を参照した他の変数は、正しく値が変わります。
上記の例でいけば、PRJ_SUFFIXはprojAのときは正しく"_A"が設定され、それを参照したOBJDIRも"obj_A"となります。

しかし、問題なのはターゲットにある変数で、例えば以下の場合。
$(OBJS): $(OBJDIR)/%.o: %.c
    @if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR);fi
    gcc -o $@ $(CFLAGS) -c $<


このときの「ターゲット」としてはprojA特有の変数によって$(OBJDIR)/%.oは"obj_A/%.o"となっているのでいいのですが、自動変数である$@が正しく設定されないのです。。projA特有の変数が空の状態で設定されるので、この場合$@が"obj/%.o"という値を返してきます。

これ、ほんと悩みましたよ。。echoで出してみてやっと理解。
おそらく$@だけは最初の処理で確定してしまうのでしょうね。
ちなみに、PRJ_SUFFIXを外部から環境変数として渡すと期待通りの動きをするので、余計悩みました。

ということで、正しく動くmakefileは以下です。
projA: PRJ_SUFFIX=_A
projA: proj

projB: PRJ_SUFFIX=_B
projB: proj

OBJDIR=obj$(PRJ_SUFFIX)
BINDIR=bin$(PRJ_SUFFIX)
SRCS=main.c tool.c
OBJS=$(patsubst %.c,$(OBJDIR)/%.o,$(SRCS))
CFLAGS=-D__DEF$(PRJ_SUFFIX)__

proj: $(BINDIR)/proj

$(BINDIR)/proj: $(OBJS)
    @if [ ! -e $(BINDIR) ]; then mkdir -p $(BINDIR);fi
    gcc -o $(BINDIR)/$(@F) $(OBJS)

$(OBJS): $(OBJDIR)/%.o: %.c
    @if [ ! -e $(OBJDIR) ]; then mkdir -p $(OBJDIR);fi
    gcc -o $(OBJDIR)/$(@F) $(CFLAGS) -c $<

$(@F)は、ディレクトリを除いたファイル名部分を取り出す書式です。

以下、参考URL。助かりましたぁ。

GNU make