2009-08-19 7 views
4

私はの簡単なのエンドユーザ向けスクリプト言語が必要な計算型アプリケーションの言語を評価しています。私はScalaを主な基盤言語として、Jythonをスクリプトインターフェースとして使用することを考えてきました。 Scalaの魅力は、行列オブジェクトの要素ごとの乗算のために:*のようなメソッドを定義し、それをインフィクス構文a :* bと一緒に使うことができるということです。しかし:*はPythonでは有効なメソッド名ではありません。 Jythonはこれをどのように処理しますか?ScalaとJythonのインフィックス演算子

スクリプト言語としてScalaを柔軟に使用することを検討します。しかし、タイプ推論でも、valvarと必須のタイプ定義は、matlabのような動的言語に使用される一般ユーザにとってはあまりにも多い。これとは対照的に、Booにはオプション-duckyがありますが、.NETよりもJVMを使いたいと思っています。私はScalaのための-duckyがないと仮定します。

より一般的には、潜在的ディリクレ配分をモデル化するために(http://www.cs.utah.edu/~hal/HBC/から)以下のDSLを考慮してください。

model { 
     alpha  ~ Gam(0.1,1) 
     eta  ~ Gam(0.1,1) 
     beta_{k} ~ DirSym(eta, V)   , k \in [1,K] 
     theta_{d} ~ DirSym(alpha, K)   , d \in [1,D] 
     z_{d,n} ~ Mult(theta_{d})   , d \in [1,D] , n \in [1,N_{d}] 
     w_{d,n} ~ Mult(beta_{z_{d,n}})  , d \in [1,D] , n \in [1,N_{d}] 
} 

result = model.simulate(1000) 

この構文は、階層ベイズモデリングに精通しているユーザーのための(例えばPyMCMCに比べて)素晴らしいです。 JVMには、Pythonのような基本的なスクリプト言語にアクセスできるだけでなく、そのような構文を簡単に定義できる言語がありますか?

感謝しています。

+0

ここでの議論を読んだ後、自分のカスタムメイドのDSLを使用して解析する答えを改訂しました。問題のドメインに基づいて、これが最良の方法だと思います。 –

答えて

0

EDIT:

すべての議論を読んだ後、おそらく行くための最善の方法は、あなたのDSLの文法を定義し、スカラ座の作り付けの解析ユーティリティでそれを解析することです。

あなたが達成しようとしていることはわかりません。あなたのスクリプト言語は、"何"またはの "more"になりますか?タイプですか?あなたが私に与えた例は、あなたが達成しようとしていることを記述し、実装を気にしない "what"タイプのDSL - >です。これらは、問題を説明するのに最適な言語であり、アプリケーションを構築するドメインによって、私はそれが最善の方法だと思います。ユーザーは、問題のドメインに非常に慣れ親しんだ構文で問題を記述するだけで、アプリケーションはこの説明を解析し、シミュレーションを実行するために入力として使用します。このためには、文法を構築してスカラー解析ユーティリティで解析するのが最善の方法でしょう(ユーザの小さな機能のサブセットを公開したいだけです)。

"how"スクリプトが必要な場合は、すでに設定されているスクリプト言語を使用してください(ループ、基本データ構造などを自分で実装しない限り)。

システムの設計では、常にトレードオフが行われます。ここでは、ユーザーに公開する機能の量とスクリプトの簡潔さの間にあります。私自身は、できるだけ多くの機能を公開して仕事を終え、「やり方」でやり遂げていくつもりです。ユーザーは、シミュレーションがあれば、その問題をシミュレートする方法を知る必要はありません合理的な時間内に正しい結果が得られます。

完全なスクリプト言語をユーザーに公開すると、DSLはそのスクリプト言語の小さなAPIに過ぎず、フルパワーを使用するには完全な言語を学ばなければなりません。ユーザーがフルパワーを使用することを望んでいないかもしれません(アプリに大混乱を招くかもしれません!)。アプリケーションがインターネットに接続する必要がないときに、TCPソケットのサポートなど、なぜあなたが公開するのですか?セキュリティホールの可能性があります。

--次のセクションでは、可能なスクリプト言語について説明します。上記の私の答えは、それらの使用を勧めていませんが、私は完全性のために議論を残しました。

私はそれについての経験はありませんが、Groovyをご覧ください。それは動的に型付けされたJVMのスクリプティング言語です(おそらく、JVMサポートは、おそらくinvokedynamicのためにJDK 7で良くなるでしょう)。 operator overloadingwriting DSLsのサポートも良好です。残念ながら、少なくとも私の知る限りでは、ユーザー定義の演算子をサポートしていません。

私はまだ静的な型付けが好きで、型の推論が良いと分かっているので、まだスカラーになります。スクリプティングのサポートは非​​常に優れており、ほとんどすべての言語を母国語のサポートのように見せることができます(例:俳優のライブラリーをご覧ください)。また、スクリプトを非常に短く簡潔にすることができる関数型プログラミングを非常にうまくサポートしています。また、メリットとして、Javaライブラリのすべての機能を自由に使用できます。

スクリプト言語としてscalaを使用するには、スクリプトを.scalaで終わるファイルに置き、scala filename.scalaを実行します。詳しくは、Scala as a scripting Languageを参照してください。スカラとJRubyを比較します。

+0

私はスカラを使うだけで誘惑されますが、すべての 'val '' var' 'new 'はmatlabに慣れたユーザには魅力を与えません。それはステップアップではなく一歩です。同様に、プログラマではないユーザは、単純な関数を定義するときに、型( 'Int'と' Double')について考えたくありません。 – Tristan

2

個人的には、あなたはScalaのオーバーヘッドを過大評価していると思います。この例では、:

alpha  ~ Gam(10,10) 
mu_{k} ~ NorMV(vec(0.0,1,dim), 1, dim)  , k \in [1,K] 
si2  ~ IG(10,10) 
pi  ~ DirSym(alpha, K) 
z_{n}  ~ Mult(pi)       , n \in [1,N] 
x_{n}  ~ NorMV(mu_{z_{n}}, si2, dim)  , n \in [1,N] 

は、この特定のケースでは

def alpha =     Gam(10, 10) 
def mu = 1 to 'K map (k => NorMV(Vec(0.0, 1, dim), 1, dim) 
def si2 =     IG(10, 10) 
def pi =     DirSym(alpha, 'K) 
def z  = 1 to 'N map (n => Mult(pi)) 
def x  = 1 to 'N map (n => NormMV(mu(z(n)), si2, dim)) 

のように書くことができ、ほとんど何も定義 GamVecNorMVなどを除き、行われなかった、と Symbolから暗黙的な定義を作成します Intまたは Doubleに変更し、後でそのような定義を保存するテーブルから読み込みます( loadM相当)。このような暗黙の定義は次のように行くだろう:

import scala.reflect.Manifest 
val unknowns = scala.collection.mutable.HashMap[Symbol,(Manifest[_], Any)]() 
implicit def getInt(s: Symbol)(implicit m: Manifest[Int]): Int = unknowns.get(s) match { 
    case Some((`m`, x)) => x.asInstanceOf[Int] 
    case _ => error("Undefined unknown "+s) 
} 
// similarly to getInt for any other desired type 

それはあまりにも、そのようなように書くことができます処理するために、少し異なる定義する必要があるだろう

Model (
    'alpha -> Gam(10, 10), 
    'mu -> 'n -> NorMV(Vec(0.0, 1, dim), 1, dim)  With ('k in (1 to 'K)), 
    'si2  -> IG(10, 10), 
    'pi  -> DirSym('alpha, 'K), 
    'z -> 'n -> Mult('pi)       With ('n in (1 to 'N)), 
    'x -> 'n -> NorMV('mu of ('z of 'n), 'si2, dim)) With ('n in (1 to 'N)) 
) 

その場合GamMultなどでシンボルはそれらに渡されます。しかし、 "'"の超過は​​間違いなく迷惑です。

それはHBCが、それは、このような型宣言のための臨時の必要性など独自の特異性、ですがないように、ではないインデックスの前にアンダースコア、「\in」と「~」を交換する臨時の必要性、またはpreceedする必要があるとしても、バックスラッシュ後で。 HBCやMathLabの代わりにそれを使用することによって本当の利益があるかぎり、他の人が慣れていれば、彼らはちょっと困るでしょう。

+0

郵便番号。質問の著者は、このケース(別のもので置き換えようとしているもの)のために彼がScalaで得ることのできる構文を_likes_します。あなたの提案された置換の 'def'sは、' 'val''と' 'var''と同じカテゴリになります。 –

+1

あなたは彼を誤読しました。彼が示す構文は、あなたがリンクをたどった場合、HBCと呼ばれるものによって提供されます。可能であれば、彼はそれを持っていきたいです。さて、私は彼のあなたの引用のこの異議を正確に取り上げて、彼が思うほど悪くないという主張をしています。 –

+0

そうです、申し訳ありません。それでも、多くの 'def'はおそらく彼のために' ''よりはるかに優れていません。 –

0

Javスクリプト言語(JavaScript Rhino、JRuby、Jython、Groovy)の中で明らかに疑わしいのは、ユーザ定義の演算子(これはおそらく必要でしょう)をサポートしていません。ファンもどちらもしません。

JRubyをsuperators gemと試してみてください。

+0

JavaScriptはいつJVM言語になりましたか? –

+4

Rhino ECMAScriptインプリメントが開発された1997年。 Java 6以降、Rhinoは実際にはJRE(または少なくともJDK)の標準部分です。 –

+0

JVM言語は、JVMバイトコードにコンパイルされる言語です。 Rhinoはそれをしませんよね? – skaffman