Showing posts with label functional. Show all posts
Showing posts with label functional. Show all posts

2012-11-11

read-only and write-only params

8.14: adda/cstr/function/syntax/read-only and write-only params:
 if a parameter gets a pointer, (eg, /.int)
then it can be modifying both the pointer and the int,
so, shouldn't we have a syntax for expressing
what the algorithm intends to do with both?
. so, we still need a syntax for what is read-only .
. if a parameter expects a read-only,
then we can give it a modifiable
while expecting that it won't modify it .
. how about syntax for write-only?
maybe we should use (.typemark^) for that?
[11.11:
. the latest idea obviates a read-only syntax:
(inout param's)`f(x) -- in that example,
the x param is in-mode only (read-only)
that includes both the pointer and its target .
. notice that if the input is shared by any co.programs,
then we need to lock it as read-only or copy it,
unless we expect it to rely on the interactive value .]

2012-08-26

obj' messaging to clarify what's functional

7.28: adda/function/
oop's obj' messaging as a syntax for inout params:

[8.8: 8.16: intro:
. the usual way to manage objects is to
define their interface with a datatype declaration;
eg, t.type: ( ... ) -- that interface can include
both subprograms ( f( x.t ) )
and obj'messages  ( x'f ).
. up to now, that interface declaration
was the only place where we could
define obj'messages;
whereas, subprogram could be defined anywhere:
. there are various declare blocks
( package, record, subprogram, etc).
that can instantiate objects of type t;
eg, (.int:  ... )
-- that's a block that returns an integer;
and, anywhere an object can be declared,
we can also declare subprograms that are
local to the current declare block .]

declare blocks can declare obj'messaging:
. obj'messaging can be seen as
a special style of parameter,
where f(inout x) is instead written as ( x`f ).
. in the context of a type declaration,
( x`f ) is declared simply as ( `f );
because, x is assumed to be
any of the datatype's instantiations;
so, we know what x's type is,
but in a subprogram's declaration of ( x`f )
x's type would not be known;
so, the sub's declaration
would look like this: ( (x.type)`f );
and, a generalization of this would be
(x.type1, y.type2, etc)`f
which is useful for making it obvious that
x,y,etc are all inout parameters;
then we can reserve the syntax ( f(x) )
for functional uses of x,
ie, where ( f ) is not modifying x
nor modifying anything x can access;
ie, if you want to pass a pointer, p,
for the purposes of modifying p's target,
then the needed syntax is p`f, not f(p).

2011-11-30

evlan.org describes many #addx features

10.31: news.adda/lang"evlan/
evlan.org describes many addx features:

. Kenton Varda's Evlan has many addx features;
but, it "(currently has no type system);
and, it died in 2007.10.1, when the author "(got a real job)!

. what first caught my was cap-based security:
Most of today's computer platforms operate under
a fundamental assumption that has proven utterly false:
that if a user executes a program,
the user completely trusts the program.
This assumption has been made by just about
every operating system since Unix
and is made by all popular operating systems used today.
This one assumption is arguably responsible for
the majority of end-user security problems.
It is the reason malware -- adware, spyware, and viruses --
are even possible to write,
and it is the reason even big-name software
like certain web browsers
are so hard to keep secure.
Under the classical security model,
when a user runs a piece of software,
the user is granting that software the capability
to do anything that the user can do.
Under capability-based security,
when a user runs a piece of software,
the software starts out with no capabilities whatsoever.
The user may then grant specific capabilities to the program.
For example, the user might grant the program
permission to read its data files.
The user could also control whether or not
the program may access the network, play sounds, etc.
Most importantly,
all of these abilities can be controlled
independently on a per-program basis.
. the other main idea like addx
is its being a virtual operating system
which runs on top of any other operating system;
via a virtual machine that is the sole access
to the underlying platform's OS .
. by a complete platform,
he means it is not specialized to be
efficiently accessing all of bloated unix,
but to define what it needs,
and then have the vm access what it needs
for impl'ing the Evlan virtual platform .

adda's secure by language idea:
Even better than implementing security in an operating system,
is implementing it in a programming language:
developers are able to control the capabilities available
to each piece of code independently.
Good practice, then, would be to only give each component
the bare minimum capabilities that it needs to
perform its desired operation.
And, in fact, it is easier to give fewer capabilities,
so this is what programmers will usually do.
The result is that if a security hole exists in some part of your program,
the worst an attacker can do is
gain access to the capabilities that were given to that component.
--[. keep in mind that this won't work without
also implementing security at the hardware level;
this is the level where modularity can be enforced;
otherwise, malware could just jump to
what ever code there is with the permissions it needs .
(see qubes doc's) .]
It is often possible to restrict all "dangerous" capabilities
to one very small piece of code within your program.
Then, all you have to do is make sure that
that one piece of code is secure.
When you are only dealing with a small amount of code,
it is often possible to prove that this is the case.
It is, in fact, quite possible to prove
that a program written in a capability-based language
is secure.
[. great to know if your os and every other app
-- that means esp'ly your browser --
are all written in this provable language ? ]

see: Capability-based Security is used in the
EROS operating system and the E programming language.
Also, Marc Stiegler et al.

addx's idea that concurrency is the key
to secure speed:
Evlan has strong support for highly concurrent programming
being a purely functional language,
Where automatic parallelization is not possible,
there are very lightweight threads (without stacks).
Most of today's systems use imperative languages
meant for a single CPU; eg, [written in adda:]
processAll(results#t.type).proc:
for(i.int = results`domain):
      results#i`= processItem results#i
).

. in c, it would process each item in order,
from first to last.
It does not give the system any room to
process two items in parallel
or in some arbitrary (most-efficient) order .
adda aspires to be simple:
It is far easier to remember
multiple uses for a single construct
than to remember multiple constructs.
--[. however he has ada-itis and braggs about
having only 19 keywords;
one of which is "(where)
which could have been said with a reused "(:) .]
interoperability done via compatibility layers:
If and when the legacy software is no longer in use,
the compatibility layers can be removed,
leaving only the ultra-efficient Evlan core behind.
functional:
Because Evlan is purely functional,
no function call is allowed to have "side effects".

. see www.acmqueue.com/modules.php?name=Content&pa=showpage&pid=225
(dead link, is this right: queue.acm.org/detail.cfm?id=864034)?
-- ask google where else that link can be found:

Natural programming languages and environments

Communications of the ACM September 2004/Vol. 47, No. 9
by Brad A. Myers, John F. Pane, Andy Ko
This article presents findings on natural programming languages.
(i.e. natural as in intuitive in the UserCentric way)
It advocates features for programming languages,
that are justified by these findings.
Areas include:
    SyntacticSugar, that causes fewer errors
    (it more intuitive/natural).
    Better integrated debugging-support,
    esp. for hypotheses about bug-causes.
which suggests that humans like to write rules of the form
"When condition X is true, do Y".
I am not yet sure to what extent this will
change the current system, however.
natural programming:
By "natural programming" we are aiming for
the language and environment to work the way that
nonprogrammers expect.
We argue that if the computer language were to
enable people to express algorithms and data
more like their natural expressions,
the transformation effort would be reduced.
Thus, the Natural Programming approach
is an application of the standard user-centered design process
to the specific domain of programming languages and environments.

[at that link is a] good short summary of the
Natural Programming project here at CMU.
We're affiliated with the EUSES consortium,
which is a group of universities working on
end-user software engineering.
google's 2007 Update on the Natural Programming Project
Functional Bytecode
Bytecode for the Evlan virtual machine
uses a functional representation of the code.
In contrast, the VMs of Java and .NET
use assembly-like imperative instructions.
. the GNU C Compiler's "Static Single Assignment" phase
is actually very close to being equivalent to
a purely functional language. [no overwrites]
If GCC does this internally just to make optimization easier,
then it doesn't take a huge stretch to imagine a system which
compiles imperative code to functional bytecode .
--[11.30:
. another contrast to assembly-like imperative instructions
is addm's idea for a high-level interpreter:
instead of translating from an abstract syntax tree (AST)
into a sequence of assembly instructions;
addm, the vm, would try to evaluate an AST . ]
The purpose of constraining variables to types
is to get the compiler to check your work for bugs
and optimize code as well .
. if you could specify that an index to an array
must be less than the size of the array
-- and if the compiler could then check for that --
then buffer overruns (one of the most common bugs
leading to security holes in modern software)
would be completely eliminated.
(run-time bounds checking can prevent buffer overruns,
but then users see your app shutting down unexpectedly).

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 .