関数の型を綺麗に宣言する方法
なんか、ようやく見つかった気がします。ひたすら試行錯誤の毎日でしたよ。
C言語だと、
add(int a,int b)(int){return a+b;} addn(int a)(int b)(int){return (int b)(int){return a+b;}}
とするとよいんじゃないかと。
この書き方の良い点はカリー化した場合のHaskellやMLなんかとの対象性がある点です。
Haskell等の関数適用 add 1 2と定義int->int->intに対して
カリー化された関数呼びだしaddn(1)(2)と定義(int)(int)(int)と対照的でよいのです。
しかも、パラメータの名前や型を2度書く必要がない。悪くないわけです。
しかし良いとも考えてません。なぜなら、
int a; add(int a,int b)(int);
これが対照的な宣言ではないからです。名前が前に出てきた以上、型は後ろに来るべきです。
a int; add(a int,b int)(int);
のように、名前が前にでてくるなら、ラベルとして取り扱ってしまったほうが良いと思います。
a:int; add:(a:int,b:int)(int);
これで安定すると思います。
括弧は左に連結するアイディアとも合うしいい感じっす。
これならパーサ作ってあるし。
でも、、、
a(int); inc(a(int))(int); add(a(int),b(int))(int); addn(a(int))(b(int))(int);
あるいは
a:(int); inc:(a:(int))(int); add:(a:(int),b:(int))(int); addn:(a:(int))(b:(int))(int);
のように括弧を強制したほうがよいのかもしれませんし、悪いかもしれず、よくわかりません。
add:(a:int,b:int)(int); add:(a:int,b:int)(int){return a+b;} div:(a:int,b:int)(int,int){return (a/b,a%b);} div:(a:int,b:int)(int,int){a/b,a%b} addn:(a:int)(int)(int){return (b:int)(int){return a+b};} addn:(a:int)(b:int)(int){return {return a+b};} addn:(a:int)(b:int)(int){{a+b}} addn:(a:int)(b:int)(int){a+b} addn:(a:int)(b:int)(int)a+b; main:()(){printf("hello world\n");}
ポインタ等についてはまだ考えてません。
以下、試行錯誤してたときのものです。
a) add:int(a:int,b:int); add:int(a:int,b:int){return a+b;} div:int,int(a:int,b:int){return (a/b,a%b);} addn:int(a:int)(b:int){return int(a:int){return b+a;};} これだと、関数を返す関数ってところで、混乱します。 b) add:(a:int,b:int)->int; add:(a:int,b:int)->int={return a+b;} div:(a:int,b:int)->int,int={return (a/b,a%b);} div:(a:int,b:int)->int,int={a/b,a%b} addn:(a:int)->int->int={return (b:int)->int{return a+b};} addn:(a:int)->(b:int)->int={return {return a+b};} addn:(a:int)->(b:int)->int={{a+b}} addn:(a:int)->(b:int)->int={a+b} addn:(a:int)->(b:int)->int=a+b Haskell等の関数型風。関数を返す関数ってのはカリー化された関数とも考えられます。 b2)add:(a:int,b:int)int; add:(a:int,b:int)int={return a+b;} div:(a:int,b:int)int,int={return (a/b,a%b);} div:(a:int,b:int)int,int={a/b,a%b} addn:(a:int)(b:int)int={return (b:int)->int{return a+b};} addn:(a:int)(b:int)int={return {return a+b};} 矢印を取ったら解析しずらそうです。 b3)add:(a:int,b:int):int; add:(a:int,b:int):int:{return a+b;} div:(a:int,b:int):int,int:{return (a/b,a%b);} div:(a:int,b:int):int,int:{a/b,a%b} addn:(a:int):int:int:{return (b:int):int:{return a+b};} addn:(a:int):(b:int):int:{return {return a+b};} addn:(a:int):(b:int):int:{{a+b}} addn:(a:int):(b:int):int:{a+b} addn:(a:int):(b:int):int:a+b :は->のイメージです。 コロンだらけだな。 b4)add(a int,b int)int; add(a int,b int)int{return a+b;} div(a int,b int)int,int{return (a/b,a%b);} div(a int,b int)int,int{a/b,a%b} addn(a int)(int)int{return (b int)int{return a+b};} addn(a int)(b int)int{return {return a+b};} addn(a int)(b int)int{{a+b}} addn(a int)(b int)int{a+b} addn(a int)(b int)int a+b じゃあってんで、コロン取っ払ってみてやっぱだめだ。 b5)add(a int,b int)(int); add(a int,b int)(int){return a+b;} div(a int,b int)(int,int){return (a/b,a%b);} div(a int,b int)(int,int){a/b,a%b} addn(a int)(int)(int){return (b int)int{return a+b};} addn(a int)(b int)(int){return {return a+b};} addn(a int)(b int)(int){{a+b}} addn(a int)(b int)(int){a+b} addn(a int)(b int)(int) a+b キャストなイメージ b6)add:(a int,b int)(int); add:(a int,b int)(int){return a+b;} div:(a int,b int)(int,int){return (a/b,a%b);} div:(a int,b int)(int,int){a/b,a%b} addn:(a int)(int)(int){return (b int)int{return a+b};} addn:(a int)(b int)(int){return {return a+b};} addn:(a int)(b int)(int){{a+b}} addn:(a int)(b int)(int){a+b} addn:(a int)(b int)(int) a+b キャストなイメージで、やっぱりラベルなかんじ。 関数型言語のカリー化イメージと addn 1 2 int->int->int c風の仮ーイメージ addn(1)(2) (int)(int)(int) として対応が成ってて良いかも。 b7)add:(a:int,b:int)(int); add:(a:int,b:int)(int){return a+b;} div:(a:int,b:int)(int,int){return (a/b,a%b);} div:(a:int,b:int)(int,int){a/b,a%b} addn:(a:int)(int)(int){return (b:int)->int{return a+b};} addn:(a:int)(b:int)(int){return {return a+b};} addn:(a:int)(b:int)(int){{a+b}} addn:(a:int)(b:int)(int){a+b} addn:(a:int)(b:int)(int)a+b; main:()(){printf("hello world\n");} これだ。これ。 c) add:(a:int,b:int,return:int); add:(a:int,b:int,return:int){return a + b;} div:(a:int,b:int,return:(int,int)){return (a/b,a%b);} div:(a:int,b:int,return:(int,int)){a/b,a%b} addn:(a:int,return:(b:int,return:int)){return (b:int,return:int){a+b};}; これはバッファを用意した場合に、returnってところに値を入れるっていうイメージです。 c')add:(a:int,b:int,int); add:(a:int,b:int,int){return a + b;} div:(a:int,b:int,(int,int)){return (a/b,a%b);} div:(a:int,b:int,(int,int)){a/b,a%b} addn:(a:int,(b:int,int)){return (b:int,int){a+b};}; これはバッファを用意した場合に、括弧内の最後がリターン値というお約束。 引数リストは名前が付いたりつかなかったりするものとして扱えるようになってればいいんではないかと。 d) add:(return:int,a:int,b:int); add:(return:int,a:int,b:int){return a + b;} div:(return:(int,int),a:int,b:int){return (a/b,a%b);} div:(return:(int,int),a:int,b:int){a/b,a%b} addn:(return:(return:int,b:int),a:int){return (return:int,b:int){a+b};}; リターン前に持ってきて見ましたと。あんまし筋が良くない。 d')add:(int,a:int,b:int); add:(int,a:int,b:int){return a + b;} div:((int,int),a:int,b:int){return (a/b,a%b);} div:((int,int),a:int,b:int){a/b,a%b} addn:((int,b:int),a:int){return (int,b:int){a+b};}; リターン前に持ってきて省略。あんまし筋が良くない。