Re: Accumulator syntax breaks precedence

Kevin Reid <kpreid-M/[email protected]>
Newsgroups gmane.comp.lang.e.general
Message-ID <[email protected]>
On Jan 31, 2011, at 20:47, Mark S. Miller wrote:

> On Mon, Jan 31, 2011 at 5:41 PM, Kevin Reid <kpreid-M/[email protected]>  
> wrote:
>
>> The accumulator syntax effectively forces the leftmost operator to be
>> lowest-precedence. This seems Very Surprising.
>>
>> I'm mentally filing this as yet another reason the accumulator syntax
>> needs to be killed and replaced with something less special; any
>> disagreement?
>
> No disagreement. That's why it's still off by default. What  
> replacements do
> you have in mind?

The reason the accumulator syntax is so hard to replace is that it  
provides *both* customizable accumulation *and* customizable iteration.

Note that I, at least, have almost never used accum's flexibility to  
accumulate from within multiple loops, or to use 'while' or 'if'.  
Therefore my working hypothesis is that it's not worth having syntax  
for those cases.


I would be inclined to replace it with something like series (as you  
already implemented), or stream operators (once I have streams  
designed to my satisfaction; I've recently been trying to finish that  
job).

I once had the idea of replacing the accumulation part of 'accum' with  
an object which would define the accumulation operation and could be  
used within the accumulator, but it turned out to be annoyingly  
verbose; but perhaps something can be rescued from it. Here is the old  
draft message I wrote in 2005 and never posted:

------------------------------------------------------------------------

The experimental accumulator syntax, enabled by

  pragma.enable("accumulator")

is, in my opinion, ugly. For simple cases, it is verbose, and for more  
complex uses the restriction of the loop body to "_.verb(...)" is  
inconvenient.

Reference example:

  accum [] for item in 1..10 { _.with(item ** 2) }

First, I propose an accumulator syntax that is not hardwired to loops  
and the magic _ variable/statement:

  accum out from [] {             # accumulator syntax
    for item in 1..10 {           # normal loop syntax
      out(item ** 2)              # normal call syntax on an object
    }                             #   defined by the accum ...
  }

This expands into a local binding of 'out' to an object which is only  
usable in the dynamic scope, much as 'escape' does primitively.

'out' always calls the accumulated value's "with" method. This is not  
a severe limitation, as the initial value ([]) can be a custom object.  
To allow the value to be 'resolved' into the non-wrapped desired  
result, the result of the accumulation is accmulated-value.snapshot(),  
which happens to be identity for collections.

Properties of this 'use a custom object' notion:

  (+) initial-value and means-of-accumulation become bundled in a
       single reference

  (-) the objects must be defined, which is more verbose than a
      single use, and requires them to be named or inlined

I suspect that the former may be a worthwhile advantage, as it means  
that often-reused accumulation types become named objects as opposed  
to patterns of duplicated code.

One-time cases could be simplified by a standard function:

  ? def accumBy(value, verb) {
  >   return def accumulation {
  >     to snapshot() { return value }
  >     match [=="with", args] {
  >       return accumBy(E.call(value, verb, args), verb) }
  >   }
  > }
  # value <accumBy>

  ? accum out from accumBy("", "add") { for s in ["abc", "def"] {
  >     out(s) } }
  # value: "abcdef"

Um. The existing form of this is:

  accum "" for s in ["abc", "def"] { _ + s }

I seem to have produced a non-simplification.

Supposing a custom accumulator that ignores the first argument to  
'with', we could perhaps write:

  ? accum out from stringConcatAccum { ["abc", "def"].iterate(out) }

but this is still much longer than the original.

-- 
Kevin Reid                                  <http://switchb.org/kpreid/>
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.