2011-05-02

llvm's role in addx

4.22: addm/llvm's role in addx:
. why can't addm just run llvm code?
isn't elegance a dumb place to put an asm lang?
# c-friendly:
the whole point of addm is to
minimize dependencies;
many systems have no llvm system
but do have a c compiler .
# simplicity = involvement:
. while llvm is all about efficiency,
addx is about making computers accessible .
. just as there can be
cpu's designed for a language,
addm's purpose as a virtual machine
is to match the architecture of adda .
. llvm does fit in as a module:
it would be a tremendous achievement
-- on par with Apple's llvm for obj'c --
to have a way for directly translating
from addm to llvm
rather than the c link used now:
adda -> c -> llvm .

perl(practical extraction & report lang)

4.19: adda/perl/regular expressions:
. if Perl's syntax seems too cryptic
keep in mind the built-in regular expressions .
--
. that degree of terseness should be optional;
adda should have a tool that lets you
write the expression in normal logic;
if you do know perl regex coding,
it should offer to expand that into adda logic
to confirm what was written,
and it should also convert back to regex
for those who want to keep code compact .
illustrations:
-- the comments could also provide
short and long examples of target strings .
. that would be an intuitive but compact reminder
of what the regex code meant .

4.19: adda/lang"perl/compared:

hammerprinciple.com:
Ranked highly in:
# text processing
# good library distribution mechanism.
# too easy to write code in this language
that looks like it does one thing
but actually does something else;
# tends to be terse .
# annoying syntax,
# many features which feel "tacked on".
# for casual scripting of very small projects
eg, write a command-line app
. very flexible .
Ranked low in
# very readable
# built on a small core of orthogonal features
# has a strong static type system
# code is easy to maintain.
# language is minimal
# good for teaching children to write software
# tends to be verbose

guidance from stackoverflow.com:
Coming from C, Perl's syntax is easy;
Perl offers more freedom to
do the "wrong" thing,
It's also prone to ugly code
and "stupid programmer tricks".
also "There's more than one way to
muck it up" .
As for the syntax, Larry Wall (Perl's creator)
has described it as "diagonal"
(in contrast to "orthogonal" languages).
The syntax is designed to mirror the
flexibility and expressiveness of natural language.
. code like (next unless /foo/)
can be slightly jarring at first
but you quickly realize
it flows much more smoothly.
What looks like obscure Perl syntax
is actually a regex pattern
without the (programmer) overhead of
wrapping it in a method call.

But with discipline and coding standards,
you can go far.
(see Perl::critic on CPAN)
. read Conway's "Perl Best Practices"
and Perl Testing
(the Perl community has a VERY strong testing culture).
and check your code with
perl::tidy .
This will help to keep everyone
writing in a similar fashion.
. run a smoke test with Critic on committed code;
Test::Perl::Critic goes in your t/ directory
with all your other tests .

. see the PerlMonks site,
your local Perl user group
and The Perl Review magazine.

. see the great tools & code on CPAN
-- CPAN is the most comprehensive
open source code repository of any language;
most of the code you need to write
has already been written and is available,
searchable and easy to install, from CPAN,
-- you will like how productive
this lang makes you --
Perl is an amazingly good choice when
you are writing a lot of "glue"
that has to talk to a bunch of
disparate systems or work with text.
In many ways,
my favorite platform is CPAN.
Perl just happens to be the language you have to use
to pull together the modules in CPAN.
The ability to just 'get stuff done' is dramatic
when you compare it to even
trying to figure out the API
for an equivalent chunk of code
in a more traditional high level language like Java.
A large part of that power comes from
Perl's initially-strange-seeming
'do what i mean' semantics.
. Perl is the most valuable tool
in any programmer's toolbox.

. "state of the art" modules:
# Moose - a meta object protocol for Perl
it means much of Perl6 OO is available now .
# DBIx::Class

* learning Perl5 now prepares you for Perl6.
- designed to become the lingua franca
of computer languages
Larry Wall has synthesised the best features of
all other programming paradigms
(functional, OO, logic, static, dynamic, concurrency etc)
into one language.
I predict in the next couple of years
Parrot (the Perl6 virtual machine)
and other Perl6 implementations will be released -

. a real Perl programmer has an
understandable, well-documented code base
that is easy to maintain.
. use of Perl as the main development language
has always been a successful business decision
due to the extremely high productivity of a Perl expert
compared to that of a C/C++/Java/C#/Etc expert.

There are IDEs available for Perl.
For Eclipse there is the EPIC plugin.
ActiveState has Komodo.
-- most Perl programmers seem to use
vi or emacs [they are showing their age ?]

integrating concurrency with oop

4.19: adda/oop/co/integrating concurrency with oop:
. oop was described as msg passing
and then there was said to be a complication
-- inversion of control --
because if you sent a msg
and also expected a response,
then you'd be waiting for a reply to your msg,
meaning that instead of
simply writing a function call,
you were now writing reply handlers for
every use of that function .
. the reason for the handler would be
efficiency:
if your object was getting a lot of requests,
you could be just waiting around
when you could be making more calls
or checking on other replies .
[4.20:
. but, what is there to wait about?
just have the compiler clear a flag
before a remote assignment;
then set it after the remote assignment;
and finally check for the flag
before continuing to use that var .]

. I've long assumed that oop naturally defined
a per-object granularity of concurrency
but now I'm wondering whether that assumption
really holds for my style of oop .
. I like the value-oriented paradigm
(vs the popular address-orientation);
. with value-orientation,
there are still the usual polymorphic functions;
but instead of asking an obj to operate on itself,
the functions can act like they do in
that classic example of polymorphism,
number.type: where {*,/,+,-} are
binary operations over the {N,C,Q,R,Z} subtypes .

. after a var holds a value,
new values seem to come from function assignments;
but, here's what I like about this style:
the functions don't generate garbage;
because,
they use an implicit out-mode parameter, y,
which points at whatever address
the function's result was assigned to .
. all polymorphic vars have expandable
-- but nevertheless localized -- memory
that is dealloc'd in the usual way,
whenever the owning scope retires .
. conversely,
what seems like a self-mutating procedure
is really a like the cooperation between
a function and an assignment stmt .
. the way to view self-mutators like i`+1;
is that they are simply shorthand for i`= i+1;
generally,
y`*(x) means y`= (y)*(x)
and y`f means y`= f(y); each implicitely has
an inout-mode y parameter
rather than the usual implicit out-mode y;
likewise,
to model math's use of y= f(x)
in teaching about functions,
x is the name of a function's
initial activation record,
so the full name of a formal param p,
in a function f, is f`x`p;
or just x`p means self`x`p
where self is the current function
when referring to itself anonymously .
. the interface declares y`f(x) like this:
`f(x.t).proc:
the body implements it as:
f(x.t).proc: ( y`= routine(y, x) ) .

. I also wondered how sequences are preserved;
and, from this brief survey
I discovered the need for a contiguous
(read, Quick-modify, write) critical zone;
now my job is to have it done auto'ly
without involving app developers .

. when concurrent subprograms (cosub's)
are sharing inout access to a var,
the generally required minimal cooperation
is that only one writer has access at a time,
and no reading should be allowed during a write .
. if the compiler can't prove a var is not shared
then it must assume it is,
and provide it with some cooperation scheme .
. oop's message's can serialize concurrent accesses;
but value-oriented oop doesn't require msg-passing .
. the efficient and safe way is a
compiler-administered lock system;
it raises the lock just long eno' to complete
an entire read or write .
. the use must be minimal to protect against
deadlocks and unnecessary waiting .
. another safe use is for an atomic
(read, Qmodify, write) cycle
where Qmodify represents a certain class of procedures
that are guaranteed to be free of deadlock,
because either no dependencies are required
or they have already been procured
before initiating the lock attempt;
and the procedure's loops are proven to terminate .

. when is the (read,Qmodify,write)cycle really needed?
at least for the lock itself:
ie,
redo.loop:(is lock free?
lockit else redo).
-- the generalization of that exists
whenever an externally-aliased object is
# accessed by
both parts of the same conditional
(ie, being read by the guarding expression
# modified by the guarded stmt).

function notation classes

4.12: adda/cstr/function notation classes:

. how does the type mgt express
parsing particulars?
eg, some infixes can be combined:
a*b*c = *(a,b,c),
whereas, a /b /c = *(a, /b, /c) .
so then (/) is not listable ...

types of declarations:
# unary:
eg, sin(a);

# infix listable:
*(a, ...) -- = a * b * c * ....
--. implies associativity;
ie, (a*b)*c = a*(b*c) = *(a,b,c).

# infix binary:
^(a,b) -- a^b^c = a^(b^c)
-- implies non-associativity;
ie, (a^b)^c =/= a^(b^c);
and, the given rule specifies which way to parse .
--. precedence is indicated by
the order in which operators are declared .
. can also be a prefix .
-- undeclared are assumed to be 2 args of the same type
(ie, the same supertype).

# infix or unary:
/(a=1,b) -- = 1 * /b;
-(a=0,b) -- = 0 + -b
-- /a = 1/a;

# nofix: no arg expected;
eg, pi, e, dimensions,
marks an EOterm
(is also trivially a prefix)
-- declared as having no args: x.t .

# postfix:
(x)!, -- factorial's declaration,
(having multiple parameters but of various types
counts as 1 arg of type record ):
(x.t, x.u)!.v .
[4.30: {postfix, prefix} are treated as separate functions,
like so:
()!, -- postfix
!, !() -- prefix .]

. each type class can overload an operator
as either {unary#prefix, unary#post}
or -- as in the case of Number.type --
{ infix (2 args)
, prefix (other numbers of args)
} . a symbol can be designated as
both pre- and post-fix
but cannot be both post- and in-fix .
. the one place math has a postfix is (x!).
in that case,
it's at the end of a term just like an infix
so the only way to be certain that a postfix
is not the infix found between terms
is by disallowing operators from being
both infix's and postfix's .
. postfix's can, however,
double as prefix's,
as can the infix's;
so, expecting a term and finding (!)
means the (!) is a prefix to that term;
whereas, expecting an infix or EOse
(end of subexpression) and finding (!)
means the (!) is a postfix .

. a subexpression can have multiple terms
separated by infix's;
terms are defined as being either:
nofix's: symbols accepting no args;
or a prefix followed by an arg .
. a subexpression is anything terminated by
an enclosure`end:
ie,
, . ; ) } .> end-of-file ] .

2011-05-01

label as comment and method signature keywords

4.27: adda/obj'c/param'labels:
. obj'c has non-ada formal param's:
[perform selector](SEL, withObject: x1.ID, withObject: x2.ID)
. in ada the param names must be unique
but not in obj'c .
. in ada there is both named and
positional param association;
but in obj'c there is only positional;
so it doesn't matter if the
method signature keywords aren't unique .
. adda can mirror what obj'c is doing by
using label declarations:
. if the label has no type specified,
then it's a comment,
and doesn't have to be unique; ...

4.29: adda/obj'c/method signature keywords vs param'names:
mis:
. if obj'c param'names
don't have to be unique,
then how is the body distinguishing them?
web:
for each param,
it has both a param'name,
and a method signature keyword .
. the first keyword, of course,
includes the function's verb .
. the name of the function includes
all of the method signature keywords:
( my.SEL`= @selector(setWidth:height:);
str.nsString`= "(setWidth:height:);
my`= NSSelectorFromString(str)
).
basically just a signature id:
. the fact that the msk's
(method signature keywords)
can seemingly be used for named association
is completely secondary to their function as
uniquely stating the function's name;
ie, if the function is instantiated,
then the identification occurs through the
arg`record`type;
but if the arg's aren't mentioned
then the identification can still occur
through the (now not optional)
method signature keywords .

4.22: adda/cstr/labels need no type declaration:

. the colon operator's meaning is the same as
its most frequent use in english and c:
labeling things . in that capacity,
it's not only declaring constants
(eg, x.t: value -- initializing a constant,
vs: x.t`= value -- initializing a variable .
); but also,
defining points in maps:

# a case stmt:
-- var? # val1: act1, # ...; --
a map from var`values to actions;

# named associations:
-- (param1: val1, ...) ---
-- (component1: val1, ...) --
a map from agg'components to instantiations .[4.28:

# method signature keywords:
. in order to mirror what obj'c is doing, 4.29:
each param has a 2nd label consisting of
its method signature keyword;
like so:
f(x1.t, my2ndarg: x2.t, my3rdarg: x3.t)
so,
the params and function have the usual names;
but then there is labeling for expressing
the entire signature:
(f:my2ndarg:my3rdarg:)
. if this is a unique form of overloading
then it may need a unique type id:
perhaps .sig (signature keyword)
used like this:
f( x1.t
, my2ndarg.sig: x2.t
, my3rdarg.sig: x3.t) .]

. in situations where labels can be
both declared for use as a comment
(with no declared type)
and also used for named association,
there needs to be some way of
distinguishing between the two;
because, any unexpected label should be
interpreted as either a spelling error
or a shortcut for declaring a label .

. an unambiguous way to declare a label
is to use the type`dot without mentioning the type:
(label.: );
the label is then local to the current scope block;
and, the label renames a following symbol;
or, the label names a following control structure .
[5.1:
if there's no use of a declared label,
that tells the compiler it's simply a comment ...
unless some use involved a misspelling .]

4.19: adda/type/generics:
. if you write just (var. )
ie, without a specific type
adde will complete it with an interface literal
and the interface is determined by
whatever is applied locally
(ie, it's a generic;
the system won't know until run-time testing
whether the object handles those functions .)

. notice that aggregates (arrays and records)
are using labels like a map does,
but are not sets like maps are . [ 4.29:
. mapping usually refers to a set of points;
but here, "(map) includes ada's named
associations for agg'components and parameters.
(param'lists are a form of agg':
call instantiation records).]

. you might be able to identify an agg'literal
by the thing it's being assigned to;
but you also want to support
generic agg' literals;
[5.1: that would be something like lisp
where you can send trees of symbols
which then represents a situation .]

. labels for goto's need to
define themselves as loops or exits,
eg,
myway.loop:
b?? myway
else thedoor;
thedoor.exit .
otherwise,
they are assumed to be part of
some pre-existing map`domain .

. if there is no dot with the label,
and the label doesn't match an expected map point
then adde might ask beginners
what they meant:
# a full-featured goto address?
(eg, spaghetti4.<<>>: ...) 
# a loop name (enterable only from within loop)?
# an exit (a special non-looping goto address)? .

other ideas about labels:

4.22: adda/naming/freedom and efficiency:
. one reason for not allowing
special characters in names
`~!@#$%^&*()_+-={|\}[],./:;'"
-- besides the unreadability of it --
is that the compiler would be slowed down
by every other use of a special char:
having to stop and ask:
is that in one of the current names?
or is that the start of a new symbol ??
. by optionally enclosing a name in brackets,
[`~!@#$%^&*()_+-={|\}[],./:;'"]
one can have nearly complete naming freedom
(barring only the use of
unbalanced brackets within a name)
while also keeping the compiler efficient:
the compiler just looks for the end of enclosure
without having to check through current names
just to know whether a name
continues past a special char .
. as for readability,
the adde editor allows for smart name replacements,
taking your renaming suggestions
by showing all the names in the current scope block
so it's easy to tell what will be a unique name .

other uses for the colon operator:

4.24: web.adda/standard ml's [::]-operator:
. part of pattern matching
http://en.wikipedia.org/wiki/Standard_ML
an arg with formal name of (a::b)
has declared that input will be divided in 2
and given names {a(for the first part)
b (for the 2nd part)}.

4.9: news.adda/operator-::/context definition:
. some at bigresource.com
http://mac.bigresource.com/OS-X-Leopard-Leopard-bug-that-can-cause-data-loss-hqic9R96w.html
are using :: for the context operator:
eg, (in the case of hardware version x, y is happening;)
would be stated as x :: y .

4.27: mis.adda/double colon as comment:
. the problem of confusing comments
[@] adda/obj'c/param'labels
with a map's expected keys
gave me the idea of using a [comment]:: syntax
to unambiguously use labels as comments .
. it would be similar to the other styles of comment:
--[], and ##[] .
4.28:
. however,
this use has no precident,
and would be unintuitive;
furthermore, there is no ambiguity problem;
[@] adda/cstr/labels need no type declaration
therefore any label with the usual syntax
can already serve as a comment .

2011-04-30

rethinking aggregates

4.28: adda/dstr/agg's in literal mode:

. the expression (www.the.com)
is same as (www#the#com)
except that with (www.the.com)
you know the component selectors are literals,
whereas with (www#the#com),
(the) and (com) are likely variables .

. a record field works like a based pointer,
just as an array index does,
except that the distance between components
is not constant .
. records (and even arrays)
can have their components reached literally
via something other than (#)
and the example of (www.the.com)
suggests the dot should be reused for that .
. this way it works like numbers, too:
they have 2 literal parts {frac, int}
connected by a dot
-- a model even more common than url's .
. the use of dots is well-understood,
it looks neat,
and it's easy to reach on the kybd
-- much more so than (`)
(the possessive operator).

. how can reuse of the dot then avoid
confusion with types decl's?
-- eg, A.1 vs A.anArrayType --
it requires that the entire type`name`space
is barred from being reused as a component`name;
ie, if a name already stands for a type,
it can't be used as the name for any component .
. that would be easy if there was a rule like
(type`names must be capitalized),
-- as it is in math --
but most would rather write .int than .Z .

4.29: web.adda/terminology/based pointer:
. what is term for what I like to call
offset pointer? based pointer

4.28: adda/dstr/array-record equivalence:

. wondering why records and arrays
should vary their syntax from each other:
an array is simply a record where
all components are the same type,
yet array#field
vs record`field ?
. but, in database design -- a fundamental --
there's the idea of the multiples (arrays)
vs the units (records);
just as both fractions and integers
may have the same use of digits
but nevertheless very different roles .

. look at the entire lifetime of their use,
including decl's, and the other use of (`),
is it complementary ?
. t.type: <. `f, `+, + .>
; a#.t -- a#.<. `f, `+, + .>
; r.(x.t, y.s) --. a record .
; p/.(x.t, y.s) --. pointer to same .
; b.t --. declares { b`f, b`+, b+... }.
; a#1, r#x, p/x, b`x .

. where did I get the idea that
the operator(`) could be reserved for
self-modifiers?
. can't an aggregate component be a function?
then it works just like in a type def':
when a function is part of an agg'
it has access to every other component of that agg' .
b`++, b#f(x)
. the agg' declarations themselves
don't have hidden locals;
but, if a type def includes an agg' def,
then it defines an agg whose
component functions could be accessing hidden locals .

4.19: adda/cstr/rom-address-mode params:
. [pass by ref] (aka address-mode)
is often more efficient
but in some lang's [pass by copy] (aka value-mode)
is the only sure way to know inputs aren't modified .
. the interface should make clear to the compiler
whether a certain operation is modifying or not;
only then can the compiler be efficiently helpful .
4.20:
functionals have an interface like this:
f(x), f(l,r),
whereas mutators appear like this:
`f, `++, `*(x), `+(x) .

more 2nd-thoughts for use of dot notation:

4.22: todo.adda/type/filter-class generic types:
. studying c++'s generic types, eg atomic:
http://bartoszmilewski.wordpress.com/2008/12/01/c-atomics-and-memory-ordering/
adda's syntax for the parameterized type would be:
atomic(your.type).type: ...
. a generic is normally used like this:
i.atomic(int)
-- i is a version of atomic.type --
but why not i.atomic.int ?
atomic is an important example
of a special class of generic type
in which it offers as output
the same type as was input
providing a modified but nevertheless compatible semantics .
. they would be modeled after arrays,
a#.int
which has so far escaped definition
due to its being a primitive type .
todo:
review how #(x).t, (x).t, /.t
are similar and different,
and how there can be a syntax
for defining a generic array type
had the system not already done it .
. review the named pointer theory
since it has the most in common with that .

4.20: adda/type/more use of multiple dots:
. here's another place where double typing is needed:
msg.Channel.String;
. the var"msg represents a channel
through which is passed obj's of type"string .
. it's like the array, msg#.String,
being a sort of container of strings
but numerous in the time domain
vs space domain .

other lexical change ideas:

4.22: adda/operators/ancestor scope:
. my current system defines a local as
a symbol that includes a type specification;
but, aren't there times when you'd like to
rename or otherwise access an external
as something like:
"( give me the x from however many levels above
that has this particular type) ?
. one way to do that is with a new symbol:
just as the current system allows
../x.t to mean parent scope's object of type x.t,
.../x.t could mean the same but
for any ancestor scope .

4.20: adda/numeric base syntax:
. hex could folow both dimensional syntax and subscript syntax
by treating (space)#(integer) as dimension;
eg, 7FFF #16 or (ART)#32 .
-- using either the space or the parenthetical
is needed to avoid confusing A#16
with the 16th item an array named A .
. an array would allow spacing the other way:
A# 16 -- rather than:
A #16 .

4.12: adda/cstr/pointer arithmetic:
. my first idea for distinguishing between
arithmetic on a pointer vs their targets
was to use an explicit dereference operator;
but ambiguity happens rarely
-- only when the target is a numeric type
and the operation is one that applies to pointers --
so, another idea is to use attribute syntax
to indicate when the operation is on the address .
. my first idea was ptr`addr + i,
but `addr should take the addr of the symbol;
my subsequent idea was to use array notation,
since that is what pointer arithmetic is doing:
ptr#i = ptr + i .

avoiding parentheticals for the lisp-allergic

4.9: mis.adda/syntax/semicolon-comma combination:
. (f x) can be extended with comma
if the semicolon is required for
terminating a function call;
this is good for avoiding paren's .
...
but then you can't tell whether
the ,,,; is for the fx
or for the list that contains the fx .
...
. in places that expect (;)
an optional comma-separated list is also possible;
conversely, in places where a commas delimit,
such as a list, or vector,
a semicolon provides a shortcut to lists of lists
(,,,;,,,) = ((,,,), (,,,)).
with semicolons as param terminators,
(f(,,,), g(,,,)) = (f,,,; g ,,,)
but that is confused with (f(); g())?
speaking of confusion,
if (,,,;,,,) = ((,,,), (,,,))
then you can't have sequences in param's?
you have to parenthesize them:
(,,,; ,,,) means a matrix;
(,,,(;),,,) means a list containing a sequence .
(,;
,,,;
,,) -- ragged array .
4.30: another way:
. after a symbol (whether a function or not)
if it's followed by a colon:
f:,,,; -- then it can terminated by a (;).

hybrid of efficiency and encapsulation for oop

4.8: adda/oop/hybrid of efficiency and encapsulation:

. oop's inheritance is notorious for
sharing instance var's (ivar's);
but, why can't direct access still be
more controlled, like ada param's are ?

4.10: review:
. in typical (popular) oop`inheritance,
efficiency is gained when the interface
commits to a particular list of ivar's;
the inheritor's ivar's get tacked on to
the ivar record being inherited (super's) .
. encapsulation can be maintained anyway
despite the lack of privacy,
because the super can opt to mandate
that only the super's methods
can operate on the super's ivar's .
. if opting instead to share ivar's with inheritors,
then their accesses can be done quickly
since they bypass calling a function;
but, everyone in the inheritance chain
is communicating via shared var's;
and in this way, new bugs can be caused whenever
any party of the inheritance chain gets modified .
4.10:
. one way to allow direct but controlled access
is by having optional watch functions:
. inheritors have direct access
but it's confined to reads and writes;
ie, rather than having continuous access,
it's like the ada`parameter model
where the inout param's are modeled by
copying the initial value,
working on one's own copy,
and then overwriting the param`target
when the function is returning .
. if the super wants more control over
its own ivar's,
it can put a watch on them:
after a write, it can do range testing
or check for internal consistency;
if it raises an error,
the system can know who did that last write .

. the interface shouldn't have to list ivar's;
the ivar's that are listed are simply
those meant for sharing with inheritors .
. the ivar's that actually model object state
are known only to the init functions .

SML (standard metalanguage)

4.24: news.adda/lang"sml (standard metalanguage):
. standard ml is influenced by
ISWIM (I see what it means)
which influenced not only ML,
but also many other functional languages
such as SASL, Miranda, and Haskell .
Landin's SECD machine used call-by-value;
if the imperative features are stripped out
(assignment and the J operator)
leaving a purely functional language,
it then becomes possible to switch to
lazy evaluation (vs eager evaluation);
that was the path of SASL,
KRC (Kent Recursive Calculator),
Hope, Miranda, Haskell, and Clean.
. A goal of ISWIM was to look more like
mathematical notation,
so it replaced ALGOL's ways with
the pythonic off-side rule
(newlines take the place of semicolons;
indentation represents parentheticals or begin-end pairs )
. abc and python are hardly the only off-siders:
* Boo * BuddyScript * Cobra * CoffeeScript
* Curry * F# (if #light "off" is not specified)
* Genie * Miranda * Nemerle * Occam
* PROMAL * Spin * XL * YAML .

news.adda/lang"CoffeeScript/a hll-to-hll translator:
. CoffeeScript compiles to JavaScript
adding syntactic sugar inspired by Ruby and Python
to enhance JavaScript's brevity and readability,
as well as adding more sophisticated features like
array comprehension and pattern matching.

read-only, constance, and uniqueness

4.22: adda/type/const/for shared-link parameters:

. what is the diff'tween {const, rom}?
and did you notice that in formal params,
where rom is needed,
this const syntax is not very applicable ?

. the reason for being concerned with rom
is that people would like to know
whether they can safely pass a reference .
. this should be handled as it is in Ada:
it is safe unless the parameter is
specifically marked as out-mode .
. so the question then becomes,
what is an intuitive symbol for out-mode?
. ada's goto enclosure has been written about before;
and out-mode mode param's are like goto's;
because, they are transfering control to
some surprising places .
todo:
. how was it shown
where the out-mode is happening?
eg, for an array of pointers to strings,
is the array being modified (dangling pointer risk)
or are the strings being modified ?
the out-mode syntax needs to
make this distinction easy to express .

. what if the caller provides a shared link;
and, while the caller meant for the ref'
to provide the value it represented
at the time of the call,
in fact it will be changing dynamically,
because even though the caller is suspended
the caller's co.programs are still modifying the link;
therefore:
when a link represents a value
then the shared value needs a soft-locking system:
it doesn't prevent co.programs from writing
but requires the first writer
to ask the system for a lock-removal service;
in doing that,
the system sees who the lock belongs to
and copies the current value .
. if it knows the lock owner is going to be quick
it can just high-prioritize that call,
and suspend the unlocker until then .
. this is a lot efficiency glue
so the system needs to know at call time
whether an input is large eno' to link to,
since copying makes life much simpler .

4.22: mis.adda/type/const/for non-parameters:
. while const's for param's are not an issue
(see notes about rom above)
[@] adda/type/const/for shared-link parameters
const's for symbol declarations are very useful .
. I've had problems finding a const operator
(below) [@] mis.adda/uniqueness operator
but, having the need restricted to non-parameters
makes the search moot, I thought,
as const's can be initialized with a label
rather than an assignment operator;
nevertheless,
what if uninitialized, but
intending to assign later only once?
then a const symbol would enforce
only one assignment .
. just as math uses (someone!)
to mean (exactly one),
the type system could use (type!)
to mean not just (some
of the values from this type)
but instead (exactly one
of the values from this type
will be used here).

4.22: mis.adda/uniqueness operator:
. a convenient symbol for rom
is the same as for unique,
since rom maintains a unique value across times .
. notice though, that
when I chose (!) for unique
it was because math uses it for the
unique existence quantifier;
but when (!) is used alone, without (some),
math defines it as factorial;
and what does that have to do with unique?
( recall factorial:
x! = *(^i: i= 1..x) -- very multiplicative!
) . in both of these math cases,
it matches the usual english meaning:
(very *) .
. in the case of (some!),
(exactly one) is a very useful version of
(some one) because,
(mapping to exactly one)
is an essential characteristic of functions
-- one of math's foundations .
. intuitively the name could come from
feeling very responsible:
ie, if "(some one) did it
then there is a degree of anonymity,
but if exactly (!) one member is responsible
then that one member is
very much the reason for the season .

integrating types and dimensions

4.22: todo.adda/urgent/types integrated with dimensions:
just as 9.81 m/s/s
means 9.81 * m/s/s
f(x) is a shorthand for
f @ (x);
thus, space is an overloaded infix operator
meaning either a multiply or an apply .
. it is unambiguous because of the
specific places that an apply is expected .
. symbols must declare whether they expect an arg;
therefore what follows such a symbol
must be either {arg, terminator};
otherwise, it can expect either
{ infix
, multiply`factor or dimensional
, terminator}.
todo:
still need to flesh out
how to dimension things
and declare dimensions
--
. "(dimensional) refers to numeric types:
any renaming of a numeric type
must be a dimension because it implies
a numeric amount of a certain substance;
3 tsp substance
-- tsp is a unit of volume;
hence the declaration:
( tsp.vol: 4.92892159 ml )
-- many things can be measured in 3 ways:
unit counts, volumes, and weights of masses .
. in addition to type being a special type,
there is a special class of primary dimensions:
{ volume, mass, length, time,
, electric intensity
, thermal intensity
, radiation intensity }.

unique pointers

4.21: news.adda/dstr/unique pointer:

. the idea behind the unique pointer
is that they can be safely moved between threads
and they never require locking;
--
[. I first saw this idea in ms`singularity;
the msg's are instantanious because
they involve moving
only a shared heap pointer
rather than a record between process heaps .

problems with maintenance:
. after a move for a unique pointer,
the source has to be set to null?
--
I thought a simpler idea would be
a handle to a record (pointer, owner ID );
and then, in order to use the pointer,
you had to set the owner ID to
the process you were passing it to .
. anyone using it would first have to check for
whether they actually owned it at the moment .
once they were done with it
they would hand it to the system (ID=0)
or they could communicate it to a co.process .]

making concurrent programming safer:
. he proposes to do this by
extending the type system.

. two major challenges in multithreaded programming
are identified as:
Avoiding races -- approachable,
Preventing deadlocks -- pie in the sky.

. his main reference is:
Object Types against Races (pdf):
. Cormac Flanagan and Mart ́ Abadi .
This paper investigates an approach for
statically preventing race conditions in an oop language.
The setting of this work is a variant of
Gordon and Hankin’s concurrent object calculus.
We enrich that calculus with a form of
dependent object types
that enables us to verify that threads
invoke and update methods only after
acquiring appropriate locks.
We establish that well-typed programs
do not have race conditions.

2011-03-31

dsm means full code generation

3.7: news.adda/domain-specific modeling and full code generation:
. when you hear about thousand-fold
increases in productivity from applying
industrial-age engineering techniques
it is from the use of domain-specific modeling
being the facilitator of full code generation .
. it's like the idea of a module-connection language
extended to generate code for
not just the connections but the entire app .
. it's like domain-specific support libraries
extended to include control structures
-- and anything else you need in order to
keep your hands out of source code  [3.31:
(in contrast to Literate Programming,
which eases the transition between dsm and
the chosen manual code generation) .]
ieeexplore.ieee.org`Computer 2002/(pdf)
Model-integrated computing (MIC):
Domain-Specific Modeling: Enabling Full Code Generation. To be useful, a reusable framework for
creating domain-specific design environments
must have a meta-metamodel lang
ie, generic enough to be applicable to
a wide range of domains.
meta-metamodeling:
as defined by math fundamentals of
logic, set, category, quantification, ...:
containment, module interconnection,
multiaspect modeling, inheritance,
textual-numerical attributes.
Metamodeling:
. eg, the metamodel of a fsa is a subclass of graph:
the edges are state transitions
and nodes are states .
modeling:
the model of a fsa
would then be a particular graph .
The one predefined language in this scheme
— the metamodeling language— expresses metamodels:
domain modeling languages .
. and is itself expressed in by a meta-metamodeling lang;
The MIC framework consistently applies
a meta-level architecture:
a layer is always described in terms of
the next higher layer in the hierarchy.
--[ . this is a reminder that adda is supposed to be
finding the fundamentals like math does
but in an elegant unified local-friendly language . ]
-- . the article was seen here first: softwaretechnews.thedacs.com,
and authored by metacase.com
todo:
how completely can adda merge with this?
get more .edu data about what this is .
. weed out dsl's:
Domain-Specific Languages: An Annotated Bibliography
. the key to productivity is full code generation;
that leaves you with what the modeling lang' should be;
well, starting from scratch then,
being dom'specific helps;
but you can go quite far with a general-purpose lang'
that offers user-defined control structures .

2011-02-28

modulus vs remainder

2.7, 2.16: Using the mod() function with negative numbers
"modulo" as a relation:
[pointing in the same direction on a clock]
any two numbers a and b are congruent modulo m
if (a - b) is a multiple of m.
. math's idea of "integer division":
x . . . . : 2.7, -2.7
floor(x) .: 2.0, -3.0
ceiling(x): 3.0, -2.0 .

. for both mod (modulus) and rem (remainder),
they are related to div by:
A = ( A DIV B ) * B + A % B
where % is either { rem, mod };
. {mod, rem} are similar in that
they are both consistent with a div function;
but mod's div truncates towards -∞ (negative infinity);
whereas, rem's div truncates towards zero .
. mod(-n, d) -- vs rem -- is the complement
of mod(n, d); eg,
MOD(-340,60)= 20
MOD(340,60)= 40
(40 and 20 are complementary modulo 60;
ie, 40+20 = 60).
. truncating toward -∞ (negative infinity)
means that if n (the numerator) is negative;
then the usual integer div needs to be decremented:
div = int(n/d)-1
-- so that the truncation is consistent by
always reducing the value instead of
changing it willy-nilly towards nil
(that'd be adding value when truncating negatives
while subtracting value when truncating positives).

Ada's "mod" (modulus) and "rem" (remainder):
. notice that while Ada supports both {mod, rem}
it has only rem-consistent div (truncate toward zero)
ie, observing the identity (-A)/B = -(A/B) = A/(-B)
for A,B in positives .
by contrast, Python truncates toward -infinity .
. here is Python's mod-consistent div ( % means mod )
. 123 / 10 = 12,  123 % 10 = 3
-123 / 10 = -13, -123 % 10 = 7
. 123 /-10 = -13, 123 % -10 = -7
-123 / -10 = 12, -123 % -10 = -3

translation from ada to c:
. ada's {rem, mod} is defined for (n,d) in Z
(integers, numerator and denominator can be negatives);
let c`% = abs(n) % abs(d):
-- (%) is c's symbol for remainder function --
then depending on the original signs of n,d,
use the following table to know whether to
{complement, negate} c`% .
-- complement (~) means abs(modulus) - x;
so for modulus = 5, the complement
of 1..4
is 4..1, respectively .
for rem:
. (n rem d)`sign = n`sign
details:
. when n,d are both positive,
or only d(modulus) is negative:
eg, 1...4 rem -5 = 1..4
or 1...4 rem 5 = 1..4
--> c`% .
. when n,d are both negative,
or only n is negative:
eg, -1...-4 rem -5 = -1 .. -4;
or -1...-4 rem 5 = -1..-4
--> -c`% .
for mod:
. (n mod d)`sign = d`sign;
if only n or only d is negative,
then complement .
details:
. when n,d are both positive:
eg, 1...4 mod 5 = 1..4
--> c`% .
. when n,d are both negative:
eg, -1...-4 mod -5 = -1 .. -4
--> -c`% .
. when only d(modulus) is negative:
eg, 1...4 mod -5 = -4..-1
--> -~c`% .
. when only n is negative:
eg, -1...-4 mod 5 = 4..1
--> ~c`% .

self as used by interfaces and anonymous algorithms

2.28: adda/lexeme/self/for anon'algor's and interfaces:
. the word"self is useful in 2 contexts:
# anonymous algorithm:
it means the current algorithm,
# type`interface:
it means a current instance of that type;
eg, t.type: ( self!: defines a postix operator).
. if there is an algorithm in the header
(eg, to declare algorithms that won't change
for some reason...)
then the usual scope rules prevail .

literals with type-defined syntax

2.28: adda/dstr/literals with type-defined syntax:
. one way to allow custom syntax
-- elegantly, without a bolt-on --
is to say that types can define
their own literal reader;
ie, a mini' type-specific compiler .
. this allows the grammar of literals to be
something other than a composite of native types,
defined instead as whatever is accepted
by the type's reader .
. during the adda.compiler's first pass,
it sorts out what's adda code
from what is either a string literal,
or a type-specific literal
having a reader-defined grammar .
. in subsequent passes,
it then uses the appropriate reader
to complete the translation of literals .

. a custom reader is not a security threat;
because while it is returning adda binary code,
that code itself is not runnable;
it must still be translated by trusted app's .

. if a type defines more than one reader,
then not mentioning a reader simply calls the default .
it can also be explicit in the usual way:
eg, .t`yet-another-reader
is a reader belonging to type t .

. the pattern:  x.anytype = "(...)
results in calling anytype's default reader
-- just as with: x.string = "(string's literal);
( notice .string's default reader
doesn't have to be trivial;
in c.lang, the reader treats "(\)
as an escape character;
eg, \n -> newline, \t -> tab, ... ).

. to help adda readily identify
all the type-defined syntax readers,
they should all return the same special type,
say, .addb (adda binary),
so then in type t's interface,
any functions of type .addb
will be registered as readers for type t;
eg,
( read(x.$).addb
, another-style(x.$).addb, ...)

. a quote lexeme -- '{}, '[], '() --
means do a read (translate text to adda code)
but don't eval,
whereas, a double-quote means don't even read:
it is to be considered { .string, .$ };
so, in the case of readers,
their parameter must be a double-quoted enclosure,
or some expression that returns .string;
otherwise, it's eval'd as adda code
before being given to the reader
and then it might not even be the expected .string type .

. places where literals are encountered:
# static typing:
. the var's are declared to have a particular type;
here the type is obvious;
so the type qualifier is not needed;
eg,
x.anytype`= "(this is greek to adda)
-- that invokes .anytype's default reader;
x.string`= c-style"(string's literal\n)
-- .string's c-style reader is invoked .
# dynamic typing:
-- the type is discovered at run-time --
. adda can't find a reader at compile time
unless the reader's type is specified:
eg,
say .tall can point to all types:
xc.tall`= .string`c-style"(featuring escapes\n) .
-- now xc can point at a .string at compile`time .
. if an undeclared function is given:
eg,
g.tall`= f "(something like x );
then the work is left to the run-time exec:
it sees if the current object assigned to g
does have a type that includes
the function type: f(x.$).*
(where * can be any type);
if so, then g gets whatever type obj'
that f returns .

. string literals can have the same problem as comments:
it's easy to lose the boundaries of multi-line constructs;
and, when that happens,
the code can act strangely because
the compiler thought half the code
was a comment or string;
 conversely,
if the comment or string accidently contains
the string delimiter,
some of the comment or string will be
compiled as if were code;
and if that succeeds,
the results will certainly be unintended!
. to assist the human reader,
there could be a redundant enclosure syntax:
if a string can't fit on one line,
the enclosure boundaries should be
on their own separate lines;
"(
example with
2 lines .
);
. if the text includes quote enclosures on their own line,
then the text could go in its own file:
x`= "( [!]myliteral.txt )
-- when {adda, adde} sees [ ! ] as one word,
then what follows is a command for generating text .
. a .txt file would be taken as literal text;
whereas an .adda file would be eval'd to an object
that would then be printed if not alread .string .

unary operators not always taking precedence over binary

2.7: news.adda/math/unary not always taking precedence:
. negation has the same precedence as
multiplication and division;
because, negation means mult by -1.
So -a^b should be -1*a^b = -(a^b).
details:
. programmers were accustomed to the C language,
in which unary operators such as negation
have higher precedence than any binary operator;
(and there was no exponent operator in C
to cause them to think twice about the matter).
so, when programmers use an exponent operator,
they may have wished to remain consistent with C;
however, for centuries,
the polynomial -x^2
has meant -1*x^2 = -(x^2)
not (-x)^2 = x^2 .

. look at the HP48G User Guide/order of operations:
priority#1:
Prefix functions (such as sin, ln, ...)
and Postfix functions (such as ! (factorial)).
--[. many could say negation is a prefix -();
2.16: nevertheless,
notice the way math has superscripted powers
(rather than using an operator);
as if it was an extension of the symbol's name
like the way subscripts actually are,
and thus intuitively having higher precedence
than any operation applied to the name .]
priority#2: Power (^) and square root.
priority#3: Negation (-), multiplication, and division.
--[. here is the 2nd place -() fits;
but, only because of its equvalence to -1*();
many think it's obvious that the negative
is part of the number's value .]
priority#4: Addition and subtraction.

. clarity should take precedence over correctness;
so, the system needs to ask new users
-- at least those who use the form (-x^n):
"( how would you eval -2^2 ?
{ 4, -4 } ??
. -1*2^2 is definitely = -1(2^2) = -4 .
whereas (-2)^2 = (-2)(-2) = 4 . )
. furthermore, when exporting adda`binary,
or allowing copies to text
always write it unambiguously { -(2^2), (-2)^2 }.

vertical bar for divisions not xor

2.7, 2.15: adda/vertical bar operator uses:
. the vertical bar operator has several uses
that are quite similar across most fields:
number theory:
. n|m is a truth function: does m divide n evenly?
because of that,
I wondered if it could double as the div operator;
ie, (int / int) -> Q (float or rational);
whereas (int | int) -> Z {truncate, floor, ceiling, ...}
. if you consider context, there is indeed
precidence for (n|m) as a div operator:
in number theory, (n|m) assumes
the result is being passed to a truth variable .
. this is also how (=) doubles as {equals, becomes}
in the basic.lang (eg, if a=b then a=c);
case depending on type:
# number? integer quotient;
# truth? mod = 0 .
. notice though, that the question of divisibility
is actually depending on the mod operation ...;
set theory:
{ f(x) | x`range } -- set generators
f(x) | (x in range) -- definite integrals .
-- like number theory, it concerns division:
the set is infinite until divided by
the finite range of its control variable .
linguistics:
. (a|b|c) means pick exactly one,
reminding me of unique existence;
however, in systems programming
there is often a need to apply both div's
and bit-wise xor's to the same ints;
eg, n xor (n div 31);
so, I'm wondering if I can find
something besides (|) for xor,
since it already fits nicely with div .

. math's existence operator(∃​) adds a bang(!)
to express a unique existence:
eg, ( for some! x: p(x,y) )
would mean
( for exactly one x: p(x,y) );
[2.28:
. notice how math uses separate operators
whenever there is quantification
or control var's involved;
 even though it could be more elegant
if it reused set generators:
eg, +(i.int|i = 1...n)
is a summation over 1..n;
math would prefer to present this as:
n
∑ (i)
i = 1 .
. likewise, math's ∃x(p(x)) can also be
expressed as
or( p(x)| x in universe );
\/ is math's operator for logical-or;
therefore,
in the pursuit of minimal language,]
a good symbol for unique existence
could be \! .
. xor is used often in computingand is like unique existence
but only for the special pair-wise case:
. the composition of xor's for reducing
a list larger than a pair
is not generally equivalent to an (\!);
because, recursively, an xor's return of false
may indicate either {many, none};
while a return of true indicates uniqueness;
so then here is a counter example
(existence but non-unique):
(true xor true) xor (true xor false)
(many) xor (unique) =
(false) xor (true) = true
but true was supposed to mean unique;
whereas this was an example of many,
which should have registered as false
if testing for unique existence .
. math`s symbol for xor is a circled plus
reminding us it functions as
clock addition modulo 2 .
. if restricting the arg of (\!) to pairs
a computer's xor operation can implement
unique existence .

menucode

2.4: adda/dstr/menucode:
. menucode is a variation of the index-style pointer
. it's a finite enumeration that is then mapped to
pointers or indexes .
2.14:
. what pointers and indexes have in common is
being addresses of a memory implementation .
. this is in contrast to opcodes and menucodes
which are specifying what you want to address
rather than where its address is .

clarity in a unicode world

2.2: adda/clarity in a unicode world:
oreilly commenters mention rust:
. Rust is Mozilla's new lower-level language;
it has a policy of ASCII-only lexemes.
. all platforms have Unicode libraries,
so why go ASCII-only ?  [2.9:
At the moment it’s just a matter of
keeping the lexer simple
(no character-class tables to consult)
as well as making it accessable to all unix tools .]

. I first conjectured ASCII-only was for security:
it's for the same reason that
website names should be ascii;
if you have 2 names that look the same,
but one uses european letters,
then people could get them confused .
. the question for a lang then is
how can the compiler give writers freedom
and still help readers stay unconfused?
# highlighting:
. whenever non-ascii could be confused with ascii,
it would be in a contrasting font or style .
# substitution:
. the editor makes it easy to
change variable names:
after parsing, a name is identified as a var';
and, the var links to its scope,
so, after a user has changed the var's name,
the entire text for that scope is re-displayed
so that all instances of the var's name
reflect the user's preference .

integrate with translations:
. like chrome.browser is integrated with
google-translate,
have the editor translate any foreign characters
to the user's {alphabet, vocabulary} .

2011-01-31

graphics-intensive social web

1.16: addx/architecture/graphic intensive social web:
. one way to make remote games is like mvc:
the objects are very compactly encoded at main;
there are no graphics transmitted;
instead,
the matrix describes typical shapes and positions
then updates are sent as difference matrices
which are added to the local absolute matrices,
then the local graphics engine fleshes out these codes,
first into user's preferred forms and themes,
eg, the 3-d polygon compositions,
then ray tracing from these
into the screen graphics .
. it still requires a fast large local machine,
but the networking is not the bottleneck .

concurrent search and replace

1.16: adde/search and replace:
. a concurrent search and replace (s&r)
takes a tab-tab-enter list of targets and replacements,
this way user doesn't have to worry about
ordering multiple s&r's in the case where
one replacement might contain the target of another
ie, you want only original content to be replaced,
not anything put there by the
current list of replacements .
. this can also apply session-wide:
the s&r dialog would show all your previous s&r's
and show what's been morph'd during this session .
. there's 3 classes of text to apply changes to:
{ original, s&r-morph'd, new text }.

. what if a list of searches is given
and one target is a substring of the other?
warn user you'll be doing search of largest first,
[don't warn about this again] is default true ...

1.26: eg, if I can have the s&r set:
phil -> philosophy
philip -> philosopher;
and then what it should do is check for both targets
and case:
# no match? move on;
# only one match? apply map;
# both match? apply superstring's map .

first-class gui

1.10: adde/first-class dialogs:
. in addition to being able to see the
entirety of any path of a wizard
without having to fill it out,
you can treat dialogs like files,
and do a [save as] on partially filled dialogs,
then when given a dialog,
you can use [open file] to complete the dialog .

1.17: adde/gui/what's going on?!:
. what seems to be a copy ctrl-c of the firefox address bar,
is not taking the first time,
go back and switch windows, and ctrl-c again and it works?
it needs a confirmation that this happened
like a tiny brief popup of the time .

1.20: adde/gui/receptivity:
. ubuntu.gnome.firefox surprises me with
the way it shows the cursor:
. if you lower the cursor into the firefox address box,
the entire cursor can be in the box (including the tip)
and it still doesn't turn into
the I-bar that indicates insertion;
I am intuitively used to putting the cursor near the bar,
and without noticing it turn into the I-bar
expecting the mouse-down to put me into
editing the address bar .
. ubuntu.gnome is too finicky !
it should work like this:
if you do a mouse-down in a place that doesn't respond,
it should be finding the closest thing you likely meant;
if there is more than one thing nearby,
it should use a list of nearby things,
or a magnified window of the graphics
showing where usable things are
vs where your cursor is .

1.31: adde/pervasive shortcuts:
. all the radio buttons and checkboxes
should be large eno to contain keys
to tell you how to mark them by keyboard .

byte-sized pointers

1.18: adda/dstr/byte-sized pointers:
. keep pointers small by seeing large lists
as subtrees;
one of the node types of a tree is
"(this subtree root declares a new subheap:
it includes access to a 256-size array of tree node).
. how does that scale? it does because
root of huge subtree had its own subheap
where all terminal nodes were tagged as
(this is a sys'ptr [32bit c pointer]
-- not a pair of byte-sized tree ptrs [byte'ptr])
[1.31:
. as the tree progresses downward with fanout,
it eventually consumes 256 nodes;
any tree-building further down
must be done from a new-subheap node`type
(ie, a node whose purpose is to declare that
the following subtree is based in a new subheap).
. lets say that a tree uses
2 subheaps worth of nodes;
then if the tree is balanced,
it can be built with only 2 new-subheap nodes
by putting the left and right subtrees
each in their own subheap;
if the tree is not balanced,
then space efficiency requires that subheaps be shareable,
so that many smaller subtrees can be
impl'd on the same subheap .
. to make best use of space,
the use of new-subheap node`types
must be minimized because they are overhead .]

. when having a ptr to subtree,
it needs a record:
sys`ptr to the subheap,
byte'ptr to where in the subheap subtree is rooted .

. when building trees from text, [1.31:
or when trees can be modified? ..]
then we need speed more than mem'
whereas figuring out how to pack for byte-ptr's
would be very time-consuming;
so, then these sort of trees should be word-sized .
. both sizes are distinguished from sys'pointers
with the term "(local ptr):
whereas a system pointer is logically a machine address
(practically an index into a process module),
a local ptr is always an index into the current subheap .
1.31:
. our tree node has less than 16 variants,
so the tag can fit in 4bits (a half-byte, nibble,
-- addressing a byte to extract the {hi,lo} 4bits );
the node's data will be sizes larger than a nibble,
and the tag should be at the beginning
to tell us what the rest of the node looks like;
so, in order to accommodate mem'allignment requirements,
without wasteful padding after the tag,
the subheap will have 2 forks
so that tags and data can each be
in their own arrays .

. a subheap supporting byte-ptr's
can hold only 256 nodes,
in turn needing a 128-byte chunk for the 256 * 4bit tags .
. these nodes are word sized:
#branch: (tag, left.byte-ptr, right.byte-ptr);
#leaf: (tag, symbol.word-ptr).

. subheaps are composed of chunks;
so, if a subheap is not enirely used,
it's not entirely alloc'd either .
. both byte-ptr and word-ptr subheaps
can use the same size chunks, 128 bytes,
to match the minimum chunk needed for tags .
. therefore 256*2byte data nodes = 128*2*2 = 4 chunks .
. if less than half of nodes are used,
then it can save on 2 chunks of 128 bytes .

. finally, a byte-ptr subheap needs to be
an array of 5 sys'pointers for access to the
1 tag chunk + 4 data chunks,
plus
whatever else is needed for variant tagging,
or part of an efficiency hack .

. if a large structure has a known minimum at init' time,
then it can be given a superchunk,
which is some arbitrary multiple of contiguous chunks .

2010-12-31

survey of programming architectures

11.15: web.adda/oop/architectures:

the categories of inheritance:

# type clustering (inclusion polymorphism):

. numbers are the classic type cluster;
that type's major subtypes have overlapping interfaces;
and they need a supertype to coordinate biop's
(binary operations; a function with 2 arg's;
eg, addition's signature is: +:NxN->N )
whenever the param's have unmatched subtypes
(eg, RxC->C, ZxN->Z, /:NxN->Q, ...).

type cluster/supervision models:
#coordinated:
. the set of polymorphic subtypes is fixed,
and the supertype knows how to convert between them;
because,
it knows the data formats of all its subtypes .
# translated:
. the supertype provides an all-inclusive
universal data format;
eg, numbers -> complex .
. all subtypes convert between that format
and their own .

type cluster/subtypes must include range constraints:
. range constraints are essential for efficiency
as well as stronger static typing;
because, range limits are what allow
direct use of native numeric types .
. typical native types include
{N,Z,R}{8,16,32,64,128} .

# type classing (Subtype polymorphism):
. declaring a type is a member of a class,
and is compatable with that class
by inheriting its interface;
the new type is then usable
anywhere the inherited class is . [12.31:
. the type class is defined by its interface;
any type following that interface
is considered a member of that class .
. it's not about sharing code by extension;
it's organizing hierarchies of compatability .]

# type cluster combined with type classing:
. the subtypes of a type cluster
can be type classed; eg,
a dimensioned number could inherit from int;
and then to coordinate with the numeric supertype
it uses functionality from int.type
to deal with these messages:
{ what is your numeric subtype?
, your numeric value?
, replace your numeric value with this one
} .
. with just that interface,
any subclass of any numeric subtype
can be used in any numeric operation . [12.31:
. all self-modifying operations ( x`f)
can be translated as assignments (x`= f(x));
so then the inherited subtype
provides all the transform code .]

#type classing without clustering:
11.20:
. without type clustering;
what does type classing do then?
are biop's supported? polymorphism?
. historical reasons for inheritance:
# polymorphism
# type compatability
# reuse of work .
. you want to extend a type's
structure and functionality,
not interfere with its code base,
and still be useful everywhere your ancestors are .

. in the popular oop model,
the inherited work is reused by
adding to an inherited type's
functionality and instance var'space
(creating a polymorphism in the type).
. there's type compatability because
the obj' can handle all the ancestor's
unary and self-modifying functions;
but, popular oop approaches differ on
how biop's are handled .

. the classic, math'al oop uses clusters, [12.31:
which can handle biop's because the supertype
has limited membership to its type class
and can thus know in advance
what combinations of subtypes to expect
among a biop's pair of arg's .
. in a system without clustering's
closed class of subtypes
then there is no particular type to handle
the coordination of mixed biop arg's .
(that mix can consist of any types in
one arg's ancestors, or their descendents).]

. if subtypes can redefine a biop,
then a biop's method might be arbitrated by:
# nearest common ancestor:
the arg' set's nearest common ancestor type;
# popular:
the first arg determines the method;
# translation:
. an inheritable type has a universal format
which inheritors convert to,
in order to use the root's biop method .]

# incremental composition:
. it can be simplifying to describe a type
in terms of how it differs from other types;
this case includes anything not considered to be
type clustering or subclassing .
. revisions such as removing inherited parts
can preclude type compatability;
in such cases, compatability could be declared
with the use of a conversion map .
. incremental composition provides
module operators for building in ways
familiar to lisp users:
code can read other code, modify it,
and then use it as a module definition .
[11.20:
. with incremental composition,
any inheritance behaviors should be possible;
but the built-in inheritance should be
simple, classic type clustering and classing
as described above .
. the directions of popular oop
are not helping either readability or reuse;
esp'y unrewarding is the ability to
inherit multiple implementations
that have overlapping interfaces .]

#frameworks:
11.15:
. generic types can implement frameworks:
a type is an interface with all code supplied;
a generic type
leaves some of its interface undefined
or optionally redefinable,
with the intent that parameter instantiations
are customizing the framework;
eg,
a typical gui framework would be impl'd as
a generic task type;
so that creating an obj' of that type
initiates a thread of execution
that captures all user input
and responds to these events by
calling functions supplied by the
framework's customizing init's .]

adda/oop/value types:
11.16:
. the classic use of oop is type clustering
as is done for numerics:
it provides users of the numeric library
with an effortless, automated way
to use a variety of numeric subtypes
while also employing static typing,
and enjoying any enhanced readability or safety
that may be provided by that .
. coercions and range checks can all be
tucked under the hood,
without requiring compliance from clients .
. this automation is possible because
the designer of a type cluster's supertype
is using subtype tags to determine
each value's data format .

. the supertype module is also
the only place to coordinate
multiple param's having unmatched subtypes;
after one param' is coerced to match the other,
operations involving matched binary subtypes
are then relegated to subtype modules .

11.19: intro to value`type:
. static typing generally means
that a var's allowed values are confined to
one declared type,
and perhaps also constrained;
eg, limited to a range of values,
or a specific subtype .
. if that declared type is a type cluster,
it's values will include a type tag
for use by the supertype module,
to indicate which of its subtype modules
is responsible for that data format .

. type.tags are sometimes seen as a way to
replace Static typing with ducktyping
(where the tag is used at run-time
to check that the given value has a type
that is compatible with the requested operation).
. type clustering, in contrast to ducktyping,
is static typing with polymorphism
(statically bound to the cluster's supertype);
and there, the purpose of the type.tag
is merely to allow the supertype module
to support a variety of subtypes,
usually for the efficiency to be gained
from supporting a variety of data formats;
eg,
if huge complex numbers won't be used,
then a real.tag can indicate there is
no mem' allocated for the imaginary component;
or,
if only int's within a certain range will be used,
then the format can be that of a native int,
which is considerably faster than non-native formats .

. the value's subtype (or value`type)
is contrasted with a var's subtype
to remind us that they need not be equal
as long as they are compatable;
eg,
a var' of type"real may contain
a value of type"integer;
because they are both subtypes of number,
and the integer values are a
subset of the real values
(independent of format).

. the obj's subtype puts a limit on
the value`types it can support;
eg,
while a var' of subtype"R16 (16bit float)
can coerce any ints to float,
it raises an exception if that float
can't fit in a 16-bit storage .

. another possibly interesting distinction
between var' types and value`types
is that value`types have no concept of
operating on self; [11.19:
a unary operation over a value`type
doesn't involve any addresses,
and there is nothing being modified .
. while popular oop has a var`address
modify itself with a msg,
eg, x`f;
classic oop would say that was an
assignment stmt plus a unary operation:
x`= x`type`f(x) -- shown here fully qualified
to indicate how modularity is preserved:
the function belongs to x's type .]

. adda can also enforce typing between
unrelated types like {pure number, Meters},
but the system depends on supertype designers
to correctly handle their own subtypes .

. in addition to the distinction between
{library, application} programmers,
there is also kernel mode:
the adda run-time manages all native types
so that any code that
could be responsible for system crashes
is all in one module .

10.23: news.adda/compositional modularity:
11.14: Bracha, Lindstrom 1992`Modularity meets Inheritance
We "unbundle" the roles of classes
by providing a suite of operators
independently controlling such effects as
combination, modification, encapsulation,
name resolution, and sharing,
all on the single notion of module.
All module operators are forms of inheritance.
Thus, inheritance not only is
not in conflict with modularity in our system,
but is its foundation.
This allows a previously unobtainable
spectrum of features
to be combined in a cohesive manner,
including multiple inheritance, mixins,
encapsulation and strong typing.
We demonstrate our approach in a language:
Jigsaw is modular in two senses:
# it manipulates modules,
# it is highly modular in its own conception,
permitting various module combinators to be
included, omitted, or newly constructed
in various realizations .
10.23: Banavar 1995`compositional modularity app framework:
11.14:
. it provides not only decomposition and encapsulation
but also module recomposition .
. the model of compositional modularity is itself
realized as a generic, reusable software arch',
an oo-app framework" Etyma
that borrows meta module operators
from the module manipulation lang, Jigsaw
-- Bracha 1992`modularity meets inheritance .

. it efficiently builds completions;
ie, tools for compositionally modular system .
. it uses the unix toolbox approach:
each module does just one thing well,
but has sophisticated and reliable mechanisms
for massive recomposition .
. forms of composition:
#functional: returns are piped to param's;
#data-flow: data filters piped;
#conventional modules: lib api calls;
# compositional modularity:
. interfaces and module impl's
operated on to obtain new modules .

. oop inheritance is a form of recomposition;
it's a linguistic mechanism that supports
reuse via incremental programming;
ie, describing a system in terms of
how it differs from another system .
. compositional modularity evolves
traditional modules beyond oop .

. that compositional modularity
sounds interesting,
what's the author been up to recently?
reflective cap'based security lang's!

Bracha 2010`Modules as Objects in Newspeak:
. a module can exist as several instances;
they can be mutually recursive .
. Newspeak, a msg-based lang has no globals,
and all names are late-bound (obj' msg's).
. programming to an interface (msg's vs methods)
is central to modularity .

. it features cap'based security:
# obj's can hide internals
even from other instances of the same class;
# obj's have no access to globals
thus avoiding [ambient authority]
(being modified by external agents) .
# unlike E-lang, Newspeak supports reflection .

Newspeak handles foreign functions
by wrapping them in an alien obj,
rather than let safe code
call unsafe functions directly .
--. this is the equivalent of SOA:
whatever you foreigners want to do,
do it on your own box (thread, module)
and send me the neat results .