Objective-D-Objective-Cの代替または追加

私の意見では、Objective-Cは多くの問題を抱えた非常に便利な言語ではありません。 ただし、この言語でiOSアプリケーションを作成する必要があります。 Objective-Cコードを生成する別の言語を開発しました。 したがって、この言語では、Objective-CおよびCの関数クラスを簡単に使用できます。 また、Objective-Cコードで生成されたクラスを簡単に使用できます。 そのため、一度に2つの言語で開発を行う機会があります。 この言語をObjective-Dと呼びました。

これは完成品ではないことを言わなければなりません。 私は自分のニーズに合わせてこの言語を開発したので、まだ多くのバグと欠点があります。 Haskellで言語の開発を行いましたが、これがこの言語での最初の経験でした。 したがって、ソースコードはあまり良くないため、作り直すべきです。

特徴

構文
Scalaの構文は非常にコンパクトで、気に入っているので、 Scalaの構文をベースにしています。 したがって、クラス宣言は非常に単純であることが判明しました。
class Foo(bar : int) { val baz = 1 //constant var qux = 0 //mutable variable def twiceBar = bar * 2 //function } 

機能
Objective-Cの名前付きパラメーターが好きです。 これにより、コードが読みやすくなります。
 def foo(p1 : int, p2 : int) : int = p1 * p2 def bar = foo(p1 = 1, 2) 

ただし、パラメータ名が不要な場合があるため、Objective-Dでは省略できます。
 def foo(bar : int) = bar * 326 val bar = 1 foo(bar = bar) foo(bar) 

スタブクラス
これらのクラスは、Objective-DでObjective-CクラスまたはC構造体を使用できるようにするために必要です。 それらは単にクラスまたは構造のメソッドとフィールドを記述します。
 stub class XMLElement { def name : string def text : string def parent : XMLElement? def children : [XMLElement] } 

一般的なプログラミング
Objective-Cがジェネリックをサポートせず、 ダックタイピングを使用するのはひどいです。 Objective-Dでは、ジェネリックを実装し、 静的型付けを使用しています
 class Foo { var array = MutableArray<Bar>() } 

型推論
変数の型または関数の戻り値を省略できます。 自動的に計算できます。
 var i = 0 var i : int = 0 //  

特性
1つのクラスと多くの特性からクラスを継承できますが、 特性は単純なインターフェースではありません。 フィールドと関数が含まれる場合があります。 特性にコンストラクターを含めることはできません。
 trait Foo { def foo = 1 } trait Bar { var bar = 0 } class Baz extends Foo with Bar 

構造
構造内の構造と機能を定義できます。 構造はC構造で生成され、関数はC関数で生成されます。
 struct Vec2(x : float, y : float) { def dot(vec2 : Vec2) : float = x*vec2.x + y*vec2.y } 

オペレーターの過負荷
現在、これは特別な関数名(add、sub、div、mul)でのみ機能します。 しかし、私は以下を実装する予定です:
 struct Vec2(x : float, y : float) { def +(vec2 : Vec2) : float = Vec2(x + vec2.x, y + vec2.y) } 

ブロック
例でブロックの構文を示します。
 def filter(predicate : T -> bool) : [T] val array = [4, 3, 5, 1] array.filter{item : int -> item > 3} // [4, 5] array.filter{item -> item > 3 } // [4, 5] array.filter(_ > 3) // [4, 5] 

アイテムのデータ型は、ジェネリックを使用して計算できるため、省略できます。

インライン式と改行を使用できます。 例を見てみましょう:
 val a = 1 val b = 2 val s = "a = $a b = $b" 

タプル
タプルは、クラス宣言なしで値を結合するのに非常に役立ちます。 関数の戻り値として使用すると便利な場合があります。
 val tuple = (1, "foo", "bar") tuple.a == 1 tuple.b == "foo" 

怠zyな意味
これらの値は、最初の呼び出し時にのみ計算されます。
 class Foo(bar : int) { lazy val barSquare = bar * bar } 

画像マッチング
画像マッチングは、関数型プログラミングの大きなトピックです。 これにより、より簡潔でクリーンなコードを作成できます。
 def foo(bar : (int, int)) : int = case(bar) { (a, 1) -> a (0, _) -> 1 _ -> 0 } 

乗り換え
Javaでのリストが好きなので、Objective-Dに似たものを実装しました。
 enum Foo(bar : int) { baz(1) qux(2) } 

パッケージ
パッケージシステムの欠如は、Objective-Cの大きな問題であり、クラスプレフィックスがまったく好きではありません。
 package com.foo import com.baz.ParticularClass import com.bar._ 

ただし、Objective-Cではプレフィックスが必要なので、Objective-Dでバッチオブジェクトのパッケージプレフィックスを定義できます。 このプレフィックスは、生成されたクラスとファイルに追加されます。 バッチオブジェクトでは、パッケージのすべてのクラスに共通のインポートを定義することもできます。
 package com object foo { import com.bar._ val prefix = "FOO" } 

開発履歴


Raildaleの開発を始めたとき、 Cocos2DとObjective-Cを使用しました 。 その後、Cocos2Dを放棄し、開発を続けることにしたため、単にOpenGLに切り替えました。 OpenGLを最初から使用していた場合、Objective-CではなくC ++を選択できました。

開発の開始後しばらくして、Objective-Cがいらいらし始めたことに気付きました。 最初の問題は、リストがないことです。 Javaやこれに置き換わるものなど、関連するプロパティを使用した再列挙を意味します。 この問題を解決するためにいくつかの方法を思いつきましたが、それでも多くのコードが必要でした。 マクロを使用してみましたが、良い解決策が見つかりませんでした。

そして、列挙型のコードジェネレーターを開発することにしました。これは、言語指向プログラミングの通常の手法です。 これはObjective-Dの最初の部分でした:
 enum RailConnector(x : int, y : int, angle : int) { left(-1, 0, 0) bottom(0, -1, 90) top(0, 1, 270) right(1, 0, 180) } 

ジェネレーターを開発するためのプラットフォームとして、 JetBrains MPSScalaおよびHaskellの 3つの可能性から選択しました。 Haskellを選んだのは、解析用の優れたライブラリ( Parsec )を備えているためです。Haskellを試したことはありません。 Haskellは素晴らしい言語だと言わざるを得ません。

私はリストを非常に速く開発しました。 そして、不変のクラスを単純で簡潔な構文で記述するのは素晴らしいことだと思いました。これは簡単に実装できます。 そして、私はこの場合のジェネレーターを開発しました。 次に、クラスに単純な関数を記述する機能を追加し、Raildaleの開発中に機能を追加し続けました。 また、構文を強調し、簡単なリファクタリングを可能にするAppCodeのプラグインも開発しました。 これまでにObjective-Dの開発に230時間を費やしました。

Objective-Dを試す方法


誰かがObjective-Dを試したならうれしいです。私はあなたの問題を助けて解決しようとします。 誰かが開発に参加したいなら、私はとても幸せです。
  1. Objective-Dダウンロードして解凍します。
  2. Xcodeでプロジェクトを作成します。
  3. ObjDLibフォルダーをプロジェクトにコピーし、mファイルをターゲットに追加します。
  4. ターゲットにビルドフェーズを追加し( エディター ->ビルドフェーズの追加->実行スクリプトビルドフェーズの追加)、 binフォルダーのObjDファイルを呼び出します。
      $ OBJD_HOME $ / bin / ObjD 
  5. od拡張子を持つファイルを作成し、Objective-Dコードをそこに記述します。 例:
     package test class Foo(bar : int) 

  6. プロジェクトをビルドします。 hファイルとmファイルは、odファイルと同じフォルダーに生成されます。 これらのファイルをプロジェクトに追加します。

AppCode のプラグインダウンロードすることもできます

開発計画



参照資料




PSこれは私の記事の英語からの翻訳です。 サイトの規則では、「I PR」ブログに載っていない限り、記事にサイトへのリンクを挿入できないと規定されているため、これは翻訳とは異なります。 この状況についてサイト管理者に尋ねましたが、リクエストに対する応答はありませんでした。 そこで、リンクを指定しないことにしました。

Source: https://habr.com/ru/post/J209464/


All Articles