Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Rosetta Code: Accumulator factory

45 views
Skip to first unread message

Robert L.

unread,
Jan 17, 2017, 4:00:20 AM1/17/17
to
A problem posed by Paul Graham is that of creating a function
that takes a single (numeric) argument and which returns
another function that is an accumulator. The returned
accumulator function in turn also takes a single numeric
argument, and returns the sum of all the numeric values passed
in so far to that accumulator (including the initial value
passed when the accumulator was created).

Takes a number n and returns a function (lets call it g), that
takes a number i, and returns n incremented by the
accumulation of i from every call of function g(i).

Works for any numeric type-- i.e. can take both ints and
floats and returns functions that can take both ints and
floats. (It is not enough simply to convert all input to
floats. An accumulator that has only seen integers must return
integers.)

Generates functions that return the sum of every number ever
passed to them, not just the most recent. (This requires a
piece of state to hold the accumulated value, which in turn
means that pure functional languages can't be used for this
task.)

Ruby:

def factory(n)
proc{|i| n += i}
end

f20 = factory(20)
f500 = factory(500)
p f500.call(3) ; p f500[3.0] ; p f500.(3)
===>
503
506.0
509.0

p f20[2] ; p f20[2]
===>
22
24

In Forth?


--

[A] young British journalism student ... ventured to the 'refugee' camp at
Calais to report sympathetically on their 'plight.' She was given a crash
course in race realism when the poor downtrodden victims of Western oppression
subjected her to a gang-rape described by police as being of "a particularly
brutal nature."
theoccidentalobserver.net/2015/08/thoughts-on-the-german-dispossession/

Paul Rubin

unread,
Jan 17, 2017, 4:38:57 AM1/17/17
to
"Robert L." <No_spamming@noWhere_7073.org> writes:
> f20 = factory(20)
> f500 = factory(500)
> p f500.call(3) ; p f500[3.0] ; p f500.(3)

: acc ( n -- ) CREATE , DOES> ( n a -- n ) tuck @ + over ! @ ;

20 acc f20 ok
500 acc f500 ok

3 f500 . 503 ok
2 f20 . 22 ok
2 f20 . 24 ok
5 f500 . 508 ok
3 f20 . 27 ok

Anton Ertl

unread,
Jan 17, 2017, 9:01:34 AM1/17/17
to
Paul Rubin <no.e...@nospam.invalid> writes:
>"Robert L." <No_spamming@noWhere_7073.org> writes:
>> f20 = factory(20)
>> f500 = factory(500)
>> p f500.call(3) ; p f500[3.0] ; p f500.(3)
>
>: acc ( n -- ) CREATE , DOES> ( n a -- n ) tuck @ + over ! @ ;

Looking at the Rosettacode page
<https://rosettacode.org/wiki/Accumulator_factory#Forth>, Ian Osgood
has partially solved this in 2010 (in a similar way). Requirement 2
does not fit Forth at all, but I have now added an FP version and
explained the idiomatic Forth way to deal with the requirement 2.

What this example shows is that CREATE should really FALIGN its body,
otherwise we get cumbersome and inefficient use of FALIGN and
FALIGNED, like this:

: faccumulator ( r "name" -- )
create falign f,
does> ( r1 -- r2 )
faligned dup f@ f+ fdup f! ;

- anton
--
M. Anton Ertl http://www.complang.tuwien.ac.at/anton/home.html
comp.lang.forth FAQs: http://www.complang.tuwien.ac.at/forth/faq/toc.html
New standard: http://www.forth200x.org/forth200x.html
EuroForth 2016: http://www.euroforth.org/ef16/

Paul Rubin

unread,
Jan 17, 2017, 4:10:50 PM1/17/17
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> What this example shows is that CREATE should really FALIGN its body,

For small systems like Amforth, maybe it would be better to have FCREATE
and FDOES if you want float alignment. Otherwise you waste memory.

Andrew Haley

unread,
Jan 18, 2017, 4:15:29 AM1/18/17
to
I don't think it'll be a huge waste, and IMO the convenience is worth
it for the standard language. It makes more sense to have a specific
(nonstandard) unaligned CREATE for small systems. There is an obvious
analogy with ALLOCATE, which must be maximally aligned.

Andrew.

Anton Ertl

unread,
Jan 18, 2017, 8:55:48 AM1/18/17
to
Do such small systems support FP at all? AmForth does not, judging by
its reference card. My guess is that the intersection of systems that
have FP with >cell alignment requirements and that have so little
memory that the padding required these alignment requirements is
significant is empty or at least close to empty. In these few cases
following Andrew Haley's suggestion and having special CREATE variants
with lower alignment requirements (possibly even one for character
alignment) may be appropriate (of course, one had to balance the
savings against the cost of actually including such words).

Paul Rubin

unread,
Jan 18, 2017, 4:20:51 PM1/18/17
to
an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
> Do such small systems support FP at all? AmForth does not, judging by
> its reference card.

I thought the whole motivation for recognizers was that AmForth had
optional floating point and Matthias wanted a way to cleanly make
parsing of FP numbers optional too.

Albert van der Horst

unread,
Jan 18, 2017, 8:30:03 PM1/18/17
to
In article <877f5s3...@nightsong.com>,
Paul Rubin <no.e...@nospam.invalid> wrote:
>an...@mips.complang.tuwien.ac.at (Anton Ertl) writes:
>> Do such small systems support FP at all? AmForth does not, judging by
>> its reference card.
>
>I thought the whole motivation for recognizers was that AmForth had
>optional floating point and Matthias wanted a way to clerly make
>parsing of FP numbers optional too.

The original motivation was that ciforth had no $ numbers and I didn't want
that garbage in my kernel.

Groetjes Albert

P.S. Okay, sometimes I use them too.
--
Albert van der Horst, UTRECHT,THE NETHERLANDS
Economic growth -- being exponential -- ultimately falters.
albert@spe&ar&c.xs4all.nl &=n http://home.hccnet.nl/a.w.m.van.der.horst

Anton Ertl

unread,
Jan 19, 2017, 11:35:59 AM1/19/17
to
That may be the case, but MSP430 and AVR8 (the two targets of AmForth)
seem to have no FP hardware, so no change in alignment requirements.
0 new messages