Re: Iterator Syntax
by Pixel other posts by this author
May 8 2002 1:11PM messages near this date
Re: Iterator Syntax
|
Re: Iterator Syntax
Glen Starchman <glenstar2@[...].com> writes:
> On Tuesday 07 May 2002 02:47 am, Donal K. Fellows wrote:
> > "hello".each(x) {
> > print(x)
> > }
> >
> > Problem with this is probably that the first x looks like an argument
> > to each(); I suppose it is, but not in quite the normal sense in that
> > it is a sort-of output-argument. If you have local function closures
> > you should probably use those, especially if they are introspectable
> > in the number of arguments[*]. OTOH, I don't know enough about the
> > syntax of your language to know how well that'd work (Java does this
> > sort of thing, except with classes not functions, and it produces code
> > that doesn't win awards for extreme syntactic elegance.) :^/
>
> Hm... originally, I had something that looked like this:
>
> iterator_function() (block_arg,...) { block_body}
>
> That turned out to be rather hard to debug, IMO.
I don't know if you have anonymous functions, but you may consider using real
anonymous functions instead of "blocks".
Usually programming languages have:
- blocks like { ... } which are not first class (you can't pass them to
functions), allowed only for builtin constructs
- anonymous functions (lambda) which are first class constructs, but usually
less sugared and harder to use.
Solutions in various languages:
- perl: blocks and anonymous functions are nearly the same, the "sub" can be
removed when the callee declares the type (and is the first parameter)
-> very concise, but no sugar for arguments (only the ugly @_)
-> no distinction between parameter-less and parameter blocks
-> blocks allow lazy evaluation of the block
sample: map { $_[0] * 2 } (1, 2)
mapn { $_[0] + $_[1] } [1, 2], [3, 4]
sub my_or { my ($a, $b) = @_; $a || &$b }
$v = my_or(1, sub { print "foo" ; 2 });
- python: blocks are reserved for builtins. "lambda" is used for
parameter-using blocks. No special sugar for having the block separated from
the arguments
-> parameter-less blocks can be achieved with lambda *but* lambda only allow
expressions, not statements
sample: map(lambda e: e * 2, [1, 2])
map(lambda a,b: a+b, [1, 2], [3, 4])
# lambda only allow expressions. "print" being a statement, this
# can't be done
# with a special print_then:
def print_then(s, v): print s ; return v
def my_or(a, b): return a or b()
v = my_or(1, lambda: print_then("foo", 2))
- ruby: blocks are a special beast allowing arguments, and are first class.
There is a distinction between functions and parameter blocks. Anonymous
functions are emulated with blocks. You can't have default-value (?) on
blocks, blocks must use "block.call(args)" instead of "func(args)".
sample: [1, 2].map{|e| e * 2}
mapn([1, 2], [3, 4]){|a,b| a+b}
def my_or(a) a || yield end
v = my_or(1){ print "foo" ; 2 }
def my_or(a,b) a || b.call end
v = my_or(1, proc{print "foo" ; 2})
- haskell: due to lazy evaluation, parameter-less blocks are not evaluated, so
no special sugar is needed for them. All is simple :)
Also note that the sugar for anonymous functions is quite terse.
sample: map (\e -> e * 2) [1, 2] or map (* 2) [1, 2]
zipWith (+) [1, 2] [3, 4]
my_or a b = if a then 1 else b
v = my_or True (trace "foo" 2)
- ocaml: parameter-less blocks must be packed in an anonymous function.
sample: map (fun e -> e * 2) [ 1 ; 2 ] or map (( * ) 2) [ 1 ; 2 ]
map2 (+) [ 1 ; 2 ] [ 3 ; 4 ]
let my_or a b = if a then 1 else b()
let v = my_or true (fun () -> print_string "foo" ; 2)
- merd [*]: parameter-less blocks can be achieved with the magic Lazy in
arguments. The result is alike haskell
sample: (1, 2).map(e -> e * 2) or (1, 2).map(* 2)
((1, 2), (3, 4)).map2(+)
my_or(a, Lazy(b)) = a ||| b
v = my_or(1, ("foo".print ; 2))
- for more syntax for anonymous functions, look "anonymous functions" in
http://merd.net/pixel/language-study/syntax-across-languages.html
[...]
> But the iteration over multiple values would be a big tougher to intergate,
> although I did look at a top-level iterator function:
>
> iterate(a,b,c,d).each() { block}
>
> that would call the each method of each object in the chain. However, I
> couldn't think of a good use of that to save my life, so removed it.
well, this is used quite a lot in functional programming languages. If you
want to allow functional programming style... :)
[*] http://merd.net, my programming language
Thread:
Glen Starchman
Donal K. Fellows
Glen Starchman
Pixel
Glen Starchman
Buggs
Mathieu Bouchard
Buggs
Mathieu Bouchard
Glen Starchman
|