Re: [stack] recursion is too hard
William Tanksley <[email protected]>
| Newsgroups | gmane.comp.lang.concatenative |
|---|---|
| Message-ID | <1236877745.5300.1464.camel@tanksley> |
John Nowak wrote:
> William Tanksley wrote:
> > My preference is to rethink the combinator to not _need_ to be so
> > smart.
> > The first "smartness" these combinators have is that they share the
> > stack between all the executions (some of your variants copy the
> > stack,
> > which I absolutely hate).
> They wouldn't copy it in a real implementation. I only explain it that
> way because you can understand it without getting into types.
I know -- "copy the stack" is shorthand for "pass the same starting
stack to every function, then merge the results together." Only mutable
stacks need to be actually copied.
> > The first thing I'd want is to _completely_ isolate the functions from
> > each other by running each infra their own fresh stack. The problem
> > then
> > becomes how to get the data into each combinator, and how to pull it
> > out.
I still think this is the essential part of any solution.
> > My first knee-jerk solution is to have the programmer provide two
> > _additional_ quotations, one that runs before each quotation on the
> > main
> > data stack to return a tuple that'll be used as the infra stack and
> > the
> > other one to run after after each quotation on the result stack of
> > each
> > quotation and return a tuple that'll be expanded onto the stack after
> > the entire execution.
> The problem is that this is just a pain in the ass to use.
I should have emphasised this -- my "knee-jerk solution" is AKA a
"programmer wants to code a solution before understanding the problem".
Yes, it's a PITA to use, which is characteristic of attempts to
construct a generalized solution to a non-problem.
However, in order to understand the problem, it helps to understand it
in general. (Sadly, my quickly constructed idea isn't _fully_ general.)
> Ideally, we'd have a 'spread' that just "does the right thing". One
> way to do this is to allow each quotation access to *only* one value.
This doesn't "do the right thing" in general; Factor's library uses the
two-argument versions of cleave and spread fairly frequently.
> This is simple and doesn't require you to explain things in terms of
> types. The downside is that F and G can't access the rest of the
> stack. The only way to make this happen is to use "smart" combinators
> that only make sense if you know the types.
Not completely true -- my solution can also allow access to "the rest of
the stack" without a smart combinator, so long as all the parallel
quotations access the stack the same way. The 'before-each' quotation
provides that access.
If the quotations don't all access the stack the same way, neither my
solution nor a smart combinator will help.
> Such combinators would
> need to inspect the types of the functions they were given in order to
> work properly. I can give a description of how this might work if
> anyone is interested, but it's downright tedious to explain so I won't
> do it here.
Nope, I already know how they work -- essentially, they'd infer the
stack effects and generate a before-each and after-each function :-).
> Instead of the type-introspective approach, an easy workaround is to
> provide a 'spread-with' word that takes another argument which is a
> stack to use in both quotations:
> S x y {T} [F] [G] jn-spread-with == S {x T F} cat {y T G} cat
That seems (in general) harder than writing before-each and after-each,
actually.
> I should also note that none of these suggestions are currently
> typeable because they would require row variable concatenation.
Except mine -- we talked about that earlier.
> - John
-Wm