2009-12-28

parameter's datatyping

9.6: adda/syntax/signatures:
. perhaps signatures could be in sections,
so that the usual signature is in brief form first:
f.(...).t
. and then there could be details of sideaffects:
eg, (inout: ... out: ...external inout: ...external out: ...)
. also, there needs to be a cap'lang that tells more than
just whether an external is modified or read from .

9.8: adda/syntax/type naming:
. generic types include string (st),
and access modes {out (o), inout(io), const};
. a generic type is expected at end of name,
after the component type that instantiates it:
eg, ch.st.io -- inout char string .
. how are ptr's fiting into this, esp'ly in param's ?

9.11: sci.adda/syntax/inout:
[@] adda/syntax/parameter access modes
. put the {io, o} part of the name on the left: o.x.int ? .

9.12: adda/syntax/parameter access modes:

treat like components
of name can be dot separated and but(/) skip dot
. some other abbrev's can also skip dot:
^ means out;
* seems like arrows in many directions, so it means inout .

.*/.t inout pointer to type"t
.*/.*t inout pointer to inout type"t

instead of out-mode
have an init w default
-- existence of default init
implies not inout just out
. no a default means usu means param not required
it has a default address to out to .

9.26: adda/declaring externals with "<<,,,>>:
. a fun not returning anyting still returns values to externals
-- is a {proc, exe} .
. the syntax can use ada's [danger!-goto`label].sign
to indicate external places the function will "(goto) or affect .
. syntax can have both:
f(x).y <<...>>, f(x).<<...>>
[9.27: proc = << >> --. when enclosing "(all),
defines proc as able to affect any externals .]

10.2: adda/syntax/out.mode:
. use out-mode gets surrounded by << ... >> .
. if the param is a pointer not modified but target is,
f(x/.<<t>>),
else f(<<x/.t>>).
10.15: in-mode:
. instead of access.typing external in.mode's as rom,
there could be separate external's.lists for { in, out}
where in.modes were an extension of the parameter.list
while {inout, out}.modes were an extension of the result type .
eg,
f(x)<<in>>.y <<inout>>`=
'(.(x.t)<<in>>.y`t <<inout>> y`= ...)
notice that in that example,
the externals`signature was duplicated
by the {var.decl', literal.description} .
. when the function.symbol is being
initialized by a function.value
rather than listed separately in a
specification part of a library unit,
then some shortcuts can occur:
the symbol need give only param`types,
and the value need give only param`names .
. even if separated into {spec', body},
the function.symbol need list param`names only if
it intends to use them as keywords in calls
(for named parameter association ) .
. the external decl's need be listing only the names
unless the function is a lib'unit
because then there is no context from which to
look up the names and find their types .


10.13: adda/subprogram instantiations:
. recently it was assumed that
constant decl's could be used for indicating
that a parameter was in-mode;
however,
that would be confusing a constant with read-only .
. the first thing a sub'instantiation means
is that the caller is creating
-- and filling in the blanks of --
the sub's act'rec (atleast if it's going to be reentrant) .

named param's:
. even though the act'rec is taking assignments,
so that you might expect sub( formal`= actual ),
named association uses the colon syntax:
sub( formal: actual );
because it follows the pattern of
names being like keys to a map
as used in agg'literals
-- both the structures ( records, arrays ),
and the sets ( dict's, functions ) .

. if the sub' is functional, then there are no side-affects;
and the call can be replaced with the value it returns;
otherwise,
there are 2 forms of side-affects:
* the args can be {out, inout}.mode
* the sub' can access
some external symbols belonging to the caller .

. the out.mode param expects the name of an external:
sub( x: var ) .
(
. notice in.mode pointers expect either
the name of an external symbol
or possibly null if the type allows it .
. given sub( x/.t).c
and the call sub(y.t),
y`address is taken as the pointer value
since the target`type is compatable;
otherwise
the actual arg should be the same type as
the formal parameter .
) .
. the inout.mode param expects
an external that's been assigned a value:
sub( x: var`= init)
-- either before the call
or within it, as shown there .

. if the param is a pointer,
the external modifications can happen on any number of levels
depending on the depth of pointers involved .
. the most common pointer case is bi-level:
sub( x/.t ).t
-- the param is a pointer to a named typed .
. since there are really 2 obj's involved
-- both the pointer and its target --
that means an out.mode type can have
3 cases of side-affects:
{ptr, target, both};

. there are several syntactic candidates for access mode;
some guidelines are:
* the same form used for external accesses
should also be used for out.modes; eg, <<,,,>> .


* the access mode
should be viewed as a specifier,
like the way a function's arg specifies
which image to return:
so then for {out, inout} cases,
it's appending a << >> to the arg`declaration;
and within that sideaffects specifier,
it lists the parameter's affected components
with the default being all components .
eg,

sub( x/.t<< x, x/ >> ).c
-- modifying both the ptr and the ptr`target .
eg,
sub( x/.t<<>> ).c 
-- this means the same as the example above,
since (all components) is the default .
* likewise,
the same syntax can be applied to the return`type;
side-affects are considered a species of return:
eg,
sub( x ).t<< global >> .
. notice that with this syntax,
the parameterless symbol can still be declared to be
a subprogram
as the return.type's species is indicating
the program space
which includes the implied parameters:
eg,
p.<< fs >> 
-- the sideaffects specifier can be used in place of
a return`type .
*
. the <<>> is specifying {inout, out}
without specifying which one .
. this would be useful for quickly reminding users
that it's ok this hasn't been init'd by the caller,
since the sub is going to be doing it anyway .
*
. within the list of affected components
each one could have a container type of .wo (write-only);
and if no components were specified,
then wo.type could apply to the whole thing:
eg,
sub( x1.t<<wo>>, x2.t<< x`f1.wo >> ).c .
*
. conversely, the container.type of rom (read-only mem)
could single out exceptions to the sideaffect.type'ing:
eg,
sub( x.t<< x`f1.rom >> ).c .
10.17: adda/syntax/renaming of externals:
. can rename a global to
reuse global's name for local
<< x renamed y, ...>> .
10.20: adda/syntax/templates vs generators:
. to diff' templates from generators, make paren's vs brace:
(.() ... ) -- templates for one expr;
(.{} ...) -- generators;
(.{i} (.{j}, s(i,j) )) -- nested for loop:
the i,j are globally typed but locally redefined
to work the same way math's dummy var's do;
{.() ... } -- template returning a set
like a function returning a function
is returning a set .
. each comma'd section can have a return stmt .
. recursives in math are defined as:
f(x) = { 0 if x=0, otherwise g(x) },
part of adda's mission though
is to have a unified lang that is regular and less ad hoc .
f: (.(x) x?
(0: 0
, others: g(x)
)) -- f is a label for a literal function,
and the set notation is really trying to express a case stmt .

10.22: adda/syntax/renaming implicit param's:
. implicit param's,
where a subroutine expects the caller to have a local symbol
of a symbol that it accesses without going through param's,
can be renamed by the use of labels .
[10.28:
. ie, a label that doesn't have the usual address.types"{loop, jump},
and is instead a value.type that is
labeling another value.type;
that label can be viewed as {renaming, aliasing} what it's labeling .
] .

10.29: adda/syntax/param`typing/run-time vs init-time constraints:
. the param value type
needs both an initial type
and an in-process type
ie, type of var
vs subtype that caller restricts initial value to .
. that is a confusion of the tradition
which is to have an initial value indicate a default value .
. given that the initial value range indicates
an init`type constraint,
then for a syntax that would say
no init is needed,
let one of the init values be null,
and if having no init entails a default,
the syntax would say that like this:
x.t`= (null => default, ...) .
[11.9:
. there is a requirement to
have parameters be like assignments
that is conflicting with the requirement to
hold up contracts .
. the parameter's datatype indicates
the run-time interface expected of it;
however,
the parameter syntax should also have the ability
to require that the client provide
an initial value that is in some proper subset of
the run-time type .
. the simpler way around this conflict
is to declare the parameter's type to be
the initialization's type,
and then assign the parameter to a local symbol
whose type specifies the desired run-time type .
]
adda/syntax/{declared externals, scope blocks, quoted blocks}:
11.21:
. I think the initial concern during this article (started on 11.10)
was how to simplify the syntax for function literals;
ie,
if the scope blocks is .( ... )
and the functional literal is '( ... )
then are there situations where both are needed: '.( ... );
or can a quoted block always refer to a scope block?
no, they are independent:
. commands and functions need not have any locals:
eg, f`= '( ... );
and, expressions with locals need not be quoted:
eg, .( i.int`=0; 1+i) represents the value 1,
not a function literal;
[11.23:
but, what about (.(x) ... )
-- that can only be a function literal, right?
well, it could have a default init to use for eval,
but that would miss the point of the whole construct !
. it says it represents -- not a value --
but a function which happens to also include
mapping the null input .
]

. this brings up the idea that scope blocks
-- whether they are stmt's or expressions --
don't need to declare their externals;
because, they present the reader with no surprises .
. conversely,
if any subexpression can be labeled
-- tagged with a symbol --
then that label can be assigned to a function
(by quoting the label,
so that when the function is called,
it returns an eval of whatever the label refers to) .
f`= 'label .
. if that happens,
any warnings that apply to function bodies,
must also apply to labeled subexpressions .

. doing this causes the eval of f to eval label,
whose return can vary dynamically .
. this is not a problem as long as
f and the label are in the same scope;
whereas, if label is nested in another block:
eg,
f.proc; --. this is external to super's scope block .
super.label:
.( --. this scope block localizes sub.label .
sub.label: (... f`= 'sub); --. possible error .
); f --. error .
. the error here is that a local was assigned to an external,
and then the external was left dangling,
since sub was no longer defined outside of super's scope block .
. here, then, is a case where
there's no need to declare externals,
yet the situation is external-sensitive;
aside from any rules to enforce structured programming
(not jumping into the middle of control structures),
the compiler should be noticing
when external symbols are assigned quoted local labels
or pointers to any other locals;
and, should then check all exec'paths
at the end of the scope block
for whether the external is going to be left with
a dangling reference ?

. a simpler way is to let the
run-time system handle it:
. this could be done by the use of locals as
hidden external pointer variables;
and, when they are not in scope
their pointer is set to void;
so then, trying to eval a void
will raise an exception .
. in this case,
dangling ref's are no problem as long as they aren't used .

. if a function can be assigned to an out.mode parameter,
then it becomes important to know
not only sideaffects,
but also any
readable or exe'able symbols
it expects to find in the caller's scope .

11.22:

. obj's with a lifetime that can go stale include
localized labels or pointers to locals,
and values in local`space {stack, heap} .

. how can adda be free of rules about
assigning locals to externals ?
compile-time checks:
. do a check at the closing of each scope block
or a check at each assignment .
run-time checks:
. use smart pointers that are fully symbolic
so they indicate a pointer`target's valid lifetime:
every pointer includes full path .
. then during run-time,
a pointer can be compared to the current scope path
to see what's available .

. activations of functions and scope blocks
are creating records and record`extensions on the stack .
. scopes are mounted and unmounted
similar to removable drives being
parked in the sys'volumes.folder .
. in unix, everything is represented as a file,
and similarly, adda could have a process.folder,
whose subfolders would represent
all the act'rec's of current programs .
. a record can be seen as a special kind of folder:
one having a fixed number of items:
. a scope block that contains other scope blocks
will have a final item called extensions.record .
. it is either null,
indicating there is no extension currently in effect;
or it's a record containing the current scope block
which may recursively contain nested scope blocks .
. in contrast to this dynamic scope structure
is the static symbol library for the function .
. that is part of the code
so that either the run-time
or the code itself (its template)
can reflect on its own structure .
. the symbol library needs to represent
all possible act'rec ext's simultaniously,
so then they have to be named enumeration:
extension#(1..n).record .

adda/syntax/addressing template vs obj:

. for whether to get template or obj,
have processes and stack be file-based;
this is how a cli [cmd line interface]
works a scope block:
make and go to a subdir,
where the subdir is an act'rec`ext .

. an active function has both a template
that is constant
and an activation record (act'rec)
that is variable
(it's varying relative to the template
-- a parameterized template needs ram
even to hold a constant value
since that will be varying across
template instantiations ) .
. the template is often called a function literal,
while the function object (template instantiated with act'rec)
is called a closure .
[12.24: a function literal may optionally be a template
depending on whether it needs to be
instantiated with act'rec .]

. a complexity when dealing with function assignments
is that
their values can be either templates
or partially active objects;
eg, a subroutine literal is implicitely
taking as a parameter
the variables it's using from the enclosing scope .
. a symbol literal (eg, f`= 'L.label)
is [12.24: virtually refering to a variable pointer?
(this thought was forgotten)]

. by supporting first-class functions,
adda is recognizing that a function.variable
can refer to both the objects in a process,
and to the same code in its inactive template form .

. a first-class function is concerned with
not only eval'ing but constructing functions,
so it can point at parts it can't eval'
and there's a fine line with the use of
pointer to function .
. does the function point to obj or template ?

. lisp's idea of a closure
is an obj' vs symbolic closure .
. obj'closures are concerned with
keeping a function eval'able
even after its been removed from environs which
defined some of its values;
so, it replaces any such external var's
with the current value of the var .
. the symbolic closure is not concerned with
being eval'able:
it needs instead to replace ref's to externals
with refs to param's .

. keep in mind lang priorities too:
first create a simple way to do
the simple things -- what c and pascal do --
in a syntax that will still apply for the complex later .

pos"simplification:
. the simple case is concerned only with
function eval not composition
it should also make it easier to write in the current lang
(obj-c with cocoa lib's) .

12.14: adda/syntax/return:
. return could be a multi-operation obj':
representing the variable being returned
when used with assignment: return`= val;
and, representing the exit subprogram command
when given without param's: return .
. it should be building on the usual symantics for symbols
rather than creating special cases;
and assignment to a function usually means changing its function .
. stay with what's actually going on
so then people can easily remember it just by knowing
what returns and symbols are .
. the return is an implicit out.mode var' .
. "(y) is well known in math function y= f(x);
if symbol "(return) was reserved as the return var,
then instead of having a return stmt,
there could be drop out design as in pascal;
but since that is good structure whipping good ergonomics,
the exit could be reused:
(exit subprogram) instead of (exit loop name) .
. what subprogram is called exactly
would depend on how an anonymous function refers to itself:
. if it's nested then it may call itself sub,
otherwise it's self .
. whatever the name, there are 3 entities it can return from:
the immediate function, the enclosing function, or the caller .
. oop argues about whether it's agent or function that is self,
perhaps the words to use would be self.scope, super.scope .

No comments:

Post a Comment