5 ms·
In Paul Graham's Accumulator Generator comparison (http://www.paulgraham.com/accgen.html http://www.paulgraham.com/accgen.html) Ruby is now terser than any lang
by mdemare 19y ago
In Paul Graham's Accumulator Generator comparison (http://www.paulgraham.com/accgen.html http://www.paulgraham.com/accgen.html) Ruby is now terser than any language except Arc.
foo = 'n -> x -> n += x'.to_proc
f = foo[4]
f[2] # => 6
f[2] # => 8
(This would be even terser:
foo = &'n -> x -> n += x'
but the ampersand syntax is only allowed after a method call.)
- dfranke 19y agoI think Haskell is overall terser than Ruby. The trouble with the accgen test is that it's imperative, and Haskell isn't meant to be. Here's the Haskell implementation that I would submit: putStrLn "Don't do that, you nimwit!"
- yariv 19y agoThe Erlang version is unnecessarily verbose (and also semantically different) because it uses 2 processes. It can be rewritten as Foo = fun(N) -> put(var, N), fun(X) -> V = get(var) + X, put(var, V), V end end. It's not as concise as Ruby or Arc, but it's a one liner. However, similar to Haskell, this style of programming is discouraged in Erlang.
- rkts 19y agoIn ML you can get a similar terseness to that of Haskell, but with support for imperative programming. If we allow the increment function to be predefined (as the Arc example does): let inc a b = a := !a +/ b; !a then foo becomes: let foo n = inc (ref n) or, with the help of the composition operator: let (<<) f g x = f (g x) let foo = inc << ref
- kcl 19y agoThis is shorter than both the Ruby and the Arc versions: {x set y+eval x} It's in q, a verbose version of a language called k. Applying it to a symbol/variable `n will give you a functional projection you can apply to any i.
- mechanical_fish 19y agoFor comparison, the original Ruby version: def foo (n) lambda {|i| n += i } end It's five characters longer, but approximately 350% more readable. Of course, a lot of that is because I'm more familiar with standard Ruby syntax than I am with this hack... but doesn't that tend to prove my point?
- mdemare 19y agoWell, by definition it's more readable, since nobody is familiar with the new notation yet. But objectively it has problems: unnecessary def and lambda keywords, using () and || for argument lists, using def .. end and {} for scopes. There's room for improvement. Personally, I like many things from Haskell's syntax. I wish I could say this in Ruby: foo = n -> x -> n += x
- Goladus 19y agoOther measures of brevity: The original ruby definition is 15 tokens, the .to_proc version is 13 tokens. Orthogonality: to_proc 3 variables (foo, n, x) 1 method call (to_proc) 1 type of separator (') 2 assignment ops (=, +=) 2 binary operators (->, .) 9 different kinds of tokens, in 5 (arbitrary) categories. Original: 3 keywords (def, lambda, end) 3 variables (foo, n, i) 5 Separators (|, {, }, (, )) 1 assignment (+=) 12 different kinds of tokens, in 4 categories. So the only way the original ruby version comes out ahead by these measures is that it has "fewer categories" of token types that are required. Also I think that with the 'def foo' declaration, 'foo' is not technically a variable. I don't really know ruby well enough. But you get the idea.
- neelesh 19y agoThe python implementation looks overly complicated. I was thinking that the ruby and python implementations would be very similar. Here it goes def foo(n): return lambda i:n+i Tried it (Python 2.5) and it works.
- mdemare 19y agoActually it doesn't work - calling the returned lambda should increment n - your implementation doesn't.
- neelesh 19y agoThat holds true for the given ruby implementation as well, since n is incremented only in the scope of foo and not in the calling scope. def foo (n) lambda {|i| n += i } end n=5 a = foo(n) puts a.call(3) #prints 8 puts n # still prints 5. n is not incremented I agree that the python one is strictly not according to the problem definition, but for all practical purposes both python equivalents are the same, aren't they? or am I missing something?
- testapplication 19y agoThat should read: def foo(n): n = [n] def bar(i): n[0] += i return n[0] return bar Python really needs a scoping syntax to allow assignment to closed variables.