言語を選ぶ基準
私が実際に使ってもいいかなと思う言語の基準というのはいろいろあるのですけど、重視している基準に次のプログラムが書けるか、というのがあります。
それは、schemeで書くと次のプログラムです。
(define (f x) (define (g y) (+ x y)) (define (h x) (g 10)) h) ((f 10) 1) ;; => 20
他の言語を見てみると、Pythonなら次のようになりOK。
def f (x): def g (y): return x + y def h (x): return g(10) return h f(10)(1) # => 20
Cleanも当然OK
f x = h where g y = x + y h x = g 10 Start = f 10 1 // => 20
Ocamlも当然OK
# let f x = let g y = x + y in let h x = g 10 in h;; val f : int -> 'a -> int = <fun> # f 10 1;; - : int = 20
Javaは関数がないですが、クラスが代わりに使えます。どう贔屓目に見ても、簡潔さに欠けますが。
public class Main{ static abstract class Fn{ abstract int $(int i);} static Fn f (final int x){ final Fn g = new Fn(){ int $(int y){ return x + y;}}; final Fn h = new Fn(){ int $(int x){ return g.$(10);}}; return h; } public static void main(String[] args){ System.out.println(f(10).$(1)); // => 20 } }
JavaScriptもOK
function f (x){ function g (y){ return x + y;} function h (x){ return g(10);} return h; } f(10)(1); // => 20
他の言語はどうなんでしょう?
-
-
- -
-
ちなみに、私はいつもRubyでこれをやろうとしてよくわからなくなって止めてしまうのです・・・
とりあえず、次のはだめ。
irb(main):001:0> def f (x) irb(main):002:1> def g (y) x + y end irb(main):003:1> def h (x) g(10) end irb(main):004:1> h irb(main):005:1> end => nil irb(main):006:0> f(10)(1) SyntaxError: compile error (irb):6: syntax error, unexpected '(', expecting $end f(10)(1) ^ from (irb):6 from :0 irb(main):007:0> f(10) ArgumentError: wrong number of arguments (0 for 1) from (irb):4:in `h' from (irb):4:in `f' from (irb):7 from :0
こう書くとまた別のエラーに。
irb(main):001:0> def f (x) irb(main):002:1> def g (y) x + y end irb(main):003:1> Proc.new {|x| g(10)} irb(main):004:1> end => nil irb(main):005:0> f(10).call(1) NameError: undefined local variable or method `x' for main:Object from (irb):2:in `g' from (irb):3:in `f' from (irb):5 from :0
そして、次のはうまく行きそうなのですが、よくわからない結果に。
irb(main):001:0> def f (x) irb(main):002:1> g = Proc.new {|y| x + y} irb(main):003:1> h = Proc.new {|x| g.call(10)} irb(main):004:1> h irb(main):005:1> end => nil irb(main):006:0> f(10).call(1) => 11