2012-03-31

unifying generators with function literals?

3.11: adda/syntax/unifying generators with function literals?:

f^(3)(x) = f f f x -- power of a unary operator;
* (^ i:1..3  ) = 1 * 2 * 3 -- power of a binary operator
= *(1,2,3) -- that is the same as operator applied to a list,
-- and the list was generated with a power of a parenthetical .
{^ x,y:R . y=f(x) and ... ? (x,y) }
= { (x1,y1), ... }
= {x1:y1, ....} -- a function
. the list generating needs to be
integrated with the function literal,
so how are they alike?
the function literal is implicitly describing a set of points:
f(x.1..3).t: '(x+1)
= { (1, 2), (2,3), (3,4) }
= {^x.1..3 . (x, x+1) }
. but do we want our function literal to be
this: {^x.1..3 . (x, x+1) } ?

. the power operator is simplest to understand
just the way it is;
here is a new idea for the function literal:
( f(x.1..3).t: '(x+1); f ) -- returns a function .
( (x.1..3).t . x+1 ) -- returns the same function .
. when we define function this way:
f(x.1..3).t: '(x+1),
its literal is implicitly declaring the type of function it is,
the explicit way to do that is with a 2 part parenthetical;
the first part specifies a function type .
. another idea that might be simpler to remember is
( (x.1..3).t: x+1 ).
. when the function was named (f)
then the (:) was saying
the way to eval f, is this; so, likewise,
when a list starts with a function type,
the (:) is telling you how to eval this function .

. instead of having to quote the function literal,
just the fact that it's typed as a function,
should mean that the quote is implicit .
. if that's not what you mean,
you can use the eval operator (!) .

. now that we have ( typeid: value ),
we can generalize that
as the syntax for type conversions?
no, that would be confused with typdef;
so, use the dot or some new operator, like (::) ?

3.12:
. instead of this: {^x.1..3 . (x, x+1) },
we have power raised to the type,
so this: {^ (x.dom).rng |  y= x+1) };
but doesn't this have to fit in with the idea of
the power's arg' being the index variable?
* (^ x.range : f(x) )
-- this tells you nothing about the list's type,
just that the function for generating the list
has an arg in the power var's range .
. nevertheless, this {^ (x.dom).rng |  y= x+1) };
serves the same purpose because,
it's providing the function's arg as an power variable,
and that power is what generates the list of function points .

3.12.1924:
. here is the syntax that should be used:
after the power (^) there is the variable or function,
and then there is the (:);
it seemed before that this would collide with
the ability to have more than one power var,
but in that case we use a parenthetical:
{^(x,y:N): x+y+global | predicates }.
. after the (:) comes an expression that generates a list value,
then comes the div (|) whose purpose is to weed the list,
ie, for {^x | is-even(x) }, if x is-even,
then it's allowed in the list .

3.20.1123:
. how would adda's list do something equivalent to
this python expression
where there are nested for-loops?:
[terminal
for s in symbols
  for terminal in f(s)
    if s in grammar else [s]]
. the first for-loop is acting as the
generator's power var,
and then the next inner loop is a typical for-loop .
. but couldn't the for-loop be using the
same syntax as the power variable?
do they serve the same purpose ?
. well, (^x: f(x) ) means
(list = nil;
for x: list`append f(x);
be list),
. in the case of a function having a for-loop,
what's being appended is another list ?
but that would be describing a list of lists,
and that's not what we want .
. how about this:
(^ s in symbols, terminal in f(s):
s in grammar ? be terminal else be '(s) ).
. but if you have complex functions,
the most general way is, define f as a stream,
and then say (^y = f ).
or if f(x) is a stream,
then say (^x: f(x) );
eg, (^symbols:
for s in symbols:
  for terminal in f(s):
    s in grammar ? be terminal else be '(s)
).