1.7: pos.addx/security/correctness vs capability constraints:
. I'm awed at the complexity of Ada;
they go to great lengths to
help you ensure program correctness;
but I doubt it can be used by the public .
. I think it would be sufficient to ensure only that
module capabilities were expressable and enforceable;
eg, any routes to implied sideaffects
need to be declared by a module .
. if parameters have links to caller`space,
then lack of an out-mode declaration
should by an assurance that the param
has no sideaffects .
[1.8:
. when the users call an app,
they expect know its capability limits,
yet they may also expect dynamic updates,
which could change the set of
subprograms called by the app .
. how does the user stay updated to
implied changes in app capability limits,
when the app has been linked to
more powerful subprograms ?
( you might assume that if you can trust a subprogram,
then you can trust apps to use that subprogram;
a counter example is when a worker has
top security clearance to work with your gov,
but you can't allow that work to be
employed by foreign gov's) .]
. if a subprogram has capabilities that are
greater than the app calling it,
then the app needs to
declare these enabling subprograms,
or the app's stated capabilities need to be
a function of whatever the app links into
dynamically .
. if the app's capabilities changed since
the user's last ok,
then the ok from user or mgt
has to happen again,
else the app can't be allowed to run .
2012-01-31
addx's text or lexical handler
1.3: addx/addt (text handler):
[1.31: update:
addl is the lui = lexical user interface;
"(addle) also means unable to think clearly
-- just how many feel around terminals
or any command line interface! ]
[1.6: summary:
. my original vision of the addx system
would avoid the use of shell,
replacing all use of it with adde;
but in case people would prefer access via shell,
there should be a module specific to that need .
. the essential feature of other shells,
is that they use text as both the input and output,
hence the name add`text .
. the shell lets you pipe outputs of one command
to the inputs of another command,
and they all assume you are sending a text stream .
. the addt module presents a set of commands
that provide shell equivalents for everything in adde .
. the addt commands are wrappers
around addx commands that do translations
from adda and addm word code to equivalent ascii versions .
. if the addx equivalents need to be piped to or from
native shell commands,
then addt offers a translation between the native text,
and addx binary communications:
eg, some-unix-cmd | a2t | adda | t2a | another-unix-cmd .
. another idea, to avoid explicit use of {a2t, t2a},
is to have one shell within a shell like python has,
but it would emulate the native shell's language,
so that while you were still dealing with your favorite shell,
you could also mix it with addx library calls,
by having addt insert the needed conversion filters
before passing it on to the actual shell .]
1.3: intro:
. the c`main`argv and unix`conventions
(esp'ly the borne shell)
determine how the user at a command line
can communicate with a program:
the cli or shell determine how a command is parsed
into the array of ascii strings that the program sees .
1.3: first idea:
. addt is a cli tool that is first responder to
any text inputs:
. it converts text to ascii byte code
which can be passed to `main's argv .
. need to define an addx byte code that
represents addm and etree as ascii rather than ints .
[1.31: update:
addl is the lui = lexical user interface;
"(addle) also means unable to think clearly
-- just how many feel around terminals
or any command line interface! ]
[1.6: summary:
. my original vision of the addx system
would avoid the use of shell,
replacing all use of it with adde;
but in case people would prefer access via shell,
there should be a module specific to that need .
. the essential feature of other shells,
is that they use text as both the input and output,
hence the name add`text .
. the shell lets you pipe outputs of one command
to the inputs of another command,
and they all assume you are sending a text stream .
. the addt module presents a set of commands
that provide shell equivalents for everything in adde .
. the addt commands are wrappers
around addx commands that do translations
from adda and addm word code to equivalent ascii versions .
. if the addx equivalents need to be piped to or from
native shell commands,
then addt offers a translation between the native text,
and addx binary communications:
eg, some-unix-cmd | a2t | adda | t2a | another-unix-cmd .
. another idea, to avoid explicit use of {a2t, t2a},
is to have one shell within a shell like python has,
but it would emulate the native shell's language,
so that while you were still dealing with your favorite shell,
you could also mix it with addx library calls,
by having addt insert the needed conversion filters
before passing it on to the actual shell .]
1.3: intro:
. the c`main`argv and unix`conventions
(esp'ly the borne shell)
determine how the user at a command line
can communicate with a program:
the cli or shell determine how a command is parsed
into the array of ascii strings that the program sees .
1.3: first idea:
. addt is a cli tool that is first responder to
any text inputs:
. it converts text to ascii byte code
which can be passed to `main's argv .
. need to define an addx byte code that
represents addm and etree as ascii rather than ints .
security per use case
1.1: addx/security per use case:
. know your users, the security book advises?
a corollary is:
make it clear in both the code's logic
and in the user's doc's,
what you expect of users .
. it was talking about the problem of
making security a hassle for users,
when, if you thought it out better,
you could find just the security measures you need
for their use case, and then bake just that in .
. one thing I recall hating
is not knowing all the dead ends upfront .
. there's all these things that can't be done,
and you can't know about it because
"(this app is so easy, intuitive, no thick manuals, etc ).
...
. sometimes you might not know what your users expect;
so then the menu's should have a search box
in addition to the menu hierarchy;
and, if a search returns nothing,
you ask them to explain what they want that is missing .
for touchscreen users,
and for those not familiar with terminology,
use a set of menus for identifying how features are
grouped by what kinds of things they do,
and by what the feature is called .
. let the users pick a place in that tree,
and optionally give a sentence for detailing
what's missing from the tree .
. a google app engine site could
merge all these requests and build the tree;
the tree will also be offline but not always uptodate .
. know your users, the security book advises?
a corollary is:
make it clear in both the code's logic
and in the user's doc's,
what you expect of users .
. it was talking about the problem of
making security a hassle for users,
when, if you thought it out better,
you could find just the security measures you need
for their use case, and then bake just that in .
. one thing I recall hating
is not knowing all the dead ends upfront .
. there's all these things that can't be done,
and you can't know about it because
"(this app is so easy, intuitive, no thick manuals, etc ).
...
. sometimes you might not know what your users expect;
so then the menu's should have a search box
in addition to the menu hierarchy;
and, if a search returns nothing,
you ask them to explain what they want that is missing .
for touchscreen users,
and for those not familiar with terminology,
use a set of menus for identifying how features are
grouped by what kinds of things they do,
and by what the feature is called .
. let the users pick a place in that tree,
and optionally give a sentence for detailing
what's missing from the tree .
. a google app engine site could
merge all these requests and build the tree;
the tree will also be offline but not always uptodate .
addm's case instruction
addm/cstr/case/large domain space issues:
[1.8: intro:
. for a classic case stmt, one ensuring that
no more than one exec'path was activated,
the primary purpose of the variables (and arithmetic)
is to dynamically set the guard ranges .]
if case ranges can be variable expressions,
how does that work at the machine level?
. the alternative execution paths are numbered: 0...n,
so the case stmt is an array 0..n of
pointer to subroutine .
. the pointer could be an offset of the program counter,
so they can be word sized or even byte sized .
[1.8: case method depends on domain size:
. typically for each exec'path,
there is either a list of literals,
or else a pair of possibly variable expressions
delimiting a range .
. next there are 2 cases of domain space:
# small:
. the expression being cased is less than a byte,
or certainly not more than a 16bit word .
. in this case there is a direct mapping
from enum to exec'path number .
. we sort the literal cases,
thus allowing for a binary search during run-time .
. for the case ranges, a..b, c..d, ...,
we need the if/else if ... list:
case => a and case <= b ?
goto ...
else case => c and case <= d ?
goto ...
else ... .
# huge: ... ]
large domain space issues:
. how do the cases map to 0..n
when not enum literals?
that's when it loses the efficiency
that case stmt's are known for:
. it's eval'ing every exec'path guard expression
as well as the expression being cased,
then it might be reduced to crawling through
a huge {if/else if ...} list;
what it checks first might depend on profiling:
in the past eval's of this case stmt,
what percentage of time was each case chosen?
1.8: hashing intro:
. the expression is larger than small;
in this case, hashing might work?
in a hash the typical problem is
associating a name with an id# .
. when you find the name,
then you need to replace it with the id#;
you could place the string in a sorted container
in which the insertion operation was cheap;
and then do a binary search to find it,
or you could use the hash method:
. if you expect n strings,
then use an algorithm to turn the string into
a number that can range of n values;
eg, if there are less than 2*^16 values,
then your hash function should return 16bit ints .
. if 2 strings result in the same number
then they both go in the same bucket,
so when your search finds a bucket,
it has to crawl as with the binary search .
1.8: back to the casing problem:
. if the expression being cased is a huge number or string,
then with the literals used in the guard
we build a hash table,
and then hash the value being cased .
. when we find the match,
it's associated with the exec'path number we need .
[1.8: intro:
. for a classic case stmt, one ensuring that
no more than one exec'path was activated,
the primary purpose of the variables (and arithmetic)
is to dynamically set the guard ranges .]
if case ranges can be variable expressions,
how does that work at the machine level?
. the alternative execution paths are numbered: 0...n,
so the case stmt is an array 0..n of
pointer to subroutine .
. the pointer could be an offset of the program counter,
so they can be word sized or even byte sized .
[1.8: case method depends on domain size:
. typically for each exec'path,
there is either a list of literals,
or else a pair of possibly variable expressions
delimiting a range .
. next there are 2 cases of domain space:
# small:
. the expression being cased is less than a byte,
or certainly not more than a 16bit word .
. in this case there is a direct mapping
from enum to exec'path number .
. we sort the literal cases,
thus allowing for a binary search during run-time .
. for the case ranges, a..b, c..d, ...,
we need the if/else if ... list:
case => a and case <= b ?
goto ...
else case => c and case <= d ?
goto ...
else ... .
# huge: ... ]
large domain space issues:
. how do the cases map to 0..n
when not enum literals?
that's when it loses the efficiency
that case stmt's are known for:
. it's eval'ing every exec'path guard expression
as well as the expression being cased,
then it might be reduced to crawling through
a huge {if/else if ...} list;
what it checks first might depend on profiling:
in the past eval's of this case stmt,
what percentage of time was each case chosen?
1.8: hashing intro:
. the expression is larger than small;
in this case, hashing might work?
in a hash the typical problem is
associating a name with an id# .
. when you find the name,
then you need to replace it with the id#;
you could place the string in a sorted container
in which the insertion operation was cheap;
and then do a binary search to find it,
or you could use the hash method:
. if you expect n strings,
then use an algorithm to turn the string into
a number that can range of n values;
eg, if there are less than 2*^16 values,
then your hash function should return 16bit ints .
. if 2 strings result in the same number
then they both go in the same bucket,
so when your search finds a bucket,
it has to crawl as with the binary search .
1.8: back to the casing problem:
. if the expression being cased is a huge number or string,
then with the literals used in the guard
we build a hash table,
and then hash the value being cased .
. when we find the match,
it's associated with the exec'path number we need .
integrated app tutorials
1.22: adde/integrated demo's:
. you can often see vid's of how to handle a gui interface;
it would be handy to instead have
a script that enhanced your gui:
it shows a balloon msg at what to click next;
and you can hit return to have it do one step at a time:
what it says you should be doing:
eg, it points to the menu,
hitting return opens the menu,
it points to a menu item,
hitting return launches the item ... .
. it can do this because
every gui view is represented as data structures,
so the demo app is reading as text
the same thing being shown to you graphically .
. it then finds what it expects,
and sends a balloon launch of the expected item .
. this way, if the app's interface changes,
then the demo can give up gracefully
when a search fails,
rather than showing you views of the app
that don't really exist .
1.24: news.adde/Apple`Popovers:
. the feature I had for adde recently
(integrated tutorials) [@] adde/integrated demo's
is partially supported by apple now,
and goes by the name Popovers .
. you can often see vid's of how to handle a gui interface;
it would be handy to instead have
a script that enhanced your gui:
it shows a balloon msg at what to click next;
and you can hit return to have it do one step at a time:
what it says you should be doing:
eg, it points to the menu,
hitting return opens the menu,
it points to a menu item,
hitting return launches the item ... .
. it can do this because
every gui view is represented as data structures,
so the demo app is reading as text
the same thing being shown to you graphically .
. it then finds what it expects,
and sends a balloon launch of the expected item .
. this way, if the app's interface changes,
then the demo can give up gracefully
when a search fails,
rather than showing you views of the app
that don't really exist .
1.24: news.adde/Apple`Popovers:
. the feature I had for adde recently
(integrated tutorials) [@] adde/integrated demo's
is partially supported by apple now,
and goes by the name Popovers .
"( AppKit framework now includes popovers,
a new unit of content that can be positioned relative to
other content on the screen.
Popovers automatically move whenever the
positioning view moves.
You can also design popovers that can be detached,
allowing them to become a separate window. )
which scripts are in what-size utf-8 codes
adde/utf-8/which codes are in how many bytes?
1.5: todo: [done]
. in utf-8, the number of bytes per code is incremental:
ascii uses 8bytes;
then how is it divided between 2..4 bytes
along what code pages? [1.31:
11-bits in 2 bytes, -- most euro or compact langs
16-bits in 3 bytes -- math & most other lang's
21-bits in 4 bytes --
In November 2003 UTF-8 was restricted to U+10FFFF,
in order to match the constraints of the
UTF-16 character encoding.
This removed the 5 and 6-byte sequences,
and about half the 4-byte sequences.]
1.6: web:
Bits Last code point Byte 1 Byte 2..4
7 7F 0xxxxxxx
11 07FF 110xxxxx 10xxxxxx
--. Latin letters with diacritics and characters from the
-- Greek, Cyrillic, Coptic, Armenian, Hebrew, Arabic, Syriac and Tāna alphabets
16 FFFF 1110xxxx 10xxxxxx *2
--. the rest of the Basic Multilingual Plane
-- (which contains virtually all characters in common use).
21 10,FFFF 11110xxx 10xxxxxx *3
--. less common CJK characters and various historic scripts.
1.31: web: where are the math symbols? in 3-bytes:
1.5: todo: [done]
. in utf-8, the number of bytes per code is incremental:
ascii uses 8bytes;
then how is it divided between 2..4 bytes
along what code pages? [1.31:
11-bits in 2 bytes, -- most euro or compact langs
16-bits in 3 bytes -- math & most other lang's
21-bits in 4 bytes --
In November 2003 UTF-8 was restricted to U+10FFFF,
in order to match the constraints of the
UTF-16 character encoding.
This removed the 5 and 6-byte sequences,
and about half the 4-byte sequences.]
1.6: web:
Bits Last code point Byte 1 Byte 2..4
7 7F 0xxxxxxx
11 07FF 110xxxxx 10xxxxxx
--. Latin letters with diacritics and characters from the
-- Greek, Cyrillic, Coptic, Armenian, Hebrew, Arabic, Syriac and Tāna alphabets
16 FFFF 1110xxxx 10xxxxxx *2
--. the rest of the Basic Multilingual Plane
-- (which contains virtually all characters in common use).
21 10,FFFF 11110xxx 10xxxxxx *3
--. less common CJK characters and various historic scripts.
1.31: web: where are the math symbols? in 3-bytes:
Mathematical Operators (U+2200–U+22FF)
Miscellaneous Mathematical Symbols-A (U+27C0–U+27EF)
Miscellaneous Mathematical Symbols-B (U+2980–U+29FF)
Supplemental Mathematical Operators (U+2A00–U+2AFF)
Letterlike Symbols (U+2100–U+214F)
Ceilings and floors in Miscellaneous technical (U+2308–U+230B)
Geometric Shapes (U+25A0–U+25FF)
Arrows in Miscellaneous Symbols and Arrows (U+2B30–U+2B4C)
Mathematical Alphanumeric Symbols (1D400–1D7FF)
translating Cocoa's obj'c to Ada's concurrency
1.24: adda/co/translating Cocoa's obj'c to Ada's concurrency:
. Hillegass's mac book has an inspiring section on concurrency .
summary:
the key to no race conditions is no indirect use of
shared modified variables;
anything done with the Cocoa libraries
should get exec'd as a msg sent to the main thread .
. adda needs a way to know when a function is
calling something that is not thread safe,
ie, not only can it not be allowed to modify non-locals,
it can't even call anyting that would modify a non-local
-- or even read a non-local if there's a chance that
some other thread might modify it .
. or else,
it can put mutexes around code doing the reading;
or, it can put shared globals in ada's protected var,
getting all requests by queue
and putting all outputs on a temp pointer provided by caller:
eg, "( this is one of the pointers on my mailbox,
it will be reserved for your response;
I will check it for non-nil until I find something ).
. Hillegass's mac book has an inspiring section on concurrency .
summary:
the key to no race conditions is no indirect use of
shared modified variables;
anything done with the Cocoa libraries
should get exec'd as a msg sent to the main thread .
. adda needs a way to know when a function is
calling something that is not thread safe,
ie, not only can it not be allowed to modify non-locals,
it can't even call anyting that would modify a non-local
-- or even read a non-local if there's a chance that
some other thread might modify it .
. or else,
it can put mutexes around code doing the reading;
or, it can put shared globals in ada's protected var,
getting all requests by queue
and putting all outputs on a temp pointer provided by caller:
eg, "( this is one of the pointers on my mailbox,
it will be reserved for your response;
I will check it for non-nil until I find something ).
Labels:
ada,
adda,
concurrency,
dev.cocoa
alloc-init pattern's rationale
1.23: sci,bk.adda/lang"obj'c/alloc-init pattern's rationale:
. in {Buck, Yacktman}`Cocoa Design Patterns
they explain the rational for separating init from alloc;
eg, x`= NSString`alloc`init .
. alloc can be a class function because
the mem requirements are known from
the interface ivars list defined by
self and self's superclasses .
. alloc works something like malloc,
only it is accepting a list of types
and converting them into the bytes count
that the malloc needs .
. my first reaction to this convention was:
how would you know what to allocate
until you see what there is to init?
these functions should indeed be separate;
but, the init should be calling the alloc,
rather than init being handed alloc's result by parameter .
. one continuing important reason for this convention
is communicating to client who it is that should be
doing the retains:
. the convention is that convenience methods are
using your autorelease pool .
. using the alloc init is your sign that
you own it (you need to auto/release it yourself )
. other than that, I've seen no intrinsic need for it;
... but, how does inheritance complicate things?
. it looks like the main reason is legacy code:
the Cocoa library can't maintain backward compatibility
unless you follow this convention .
. the main reason alloc was a class method,
was that init should be an instance method
but alloc (the source of the instance)
would have to be from a class method
because instance methods work on instances,
so the alloc couldn't be an instance method .
. I'm not sure whether {Buck, Yacktman} said that;
however, some oop evangelist did say that,
and I'd like to show next,
why I don't think it's true .
[1.31: 1.23:
. the usual oop idioms very much depend on
the root object being a pointer to heap node;
-- where that pointer that is the same size
across all objects --
and that pointer exists even before alloc is called .
. what the object really needs in order to have
access to some instance var's,
is to belong to some specific class;
and, it could get this either by
sending an init msg to the specific class it wants
or by letting the init's param decide on a class,
based upon the type of initial value assigned
(for example, when the compiler gets a value literal,
it can infer a type class from that:
"(abc) is a string
123 is a number
(1,2,3) is an array of number
(1, "(abc)) is a record in (number, string).
) . init figures out what it needs,
and then calls an alloc to help with that .
. if the client has a preference for some alloc technique
that could be a param of the init,
initWith (source, allocWith: style ) .]
. in {Buck, Yacktman}`Cocoa Design Patterns
they explain the rational for separating init from alloc;
eg, x`= NSString`alloc`init .
. alloc can be a class function because
the mem requirements are known from
the interface ivars list defined by
self and self's superclasses .
. alloc works something like malloc,
only it is accepting a list of types
and converting them into the bytes count
that the malloc needs .
. my first reaction to this convention was:
how would you know what to allocate
until you see what there is to init?
these functions should indeed be separate;
but, the init should be calling the alloc,
rather than init being handed alloc's result by parameter .
. one continuing important reason for this convention
is communicating to client who it is that should be
doing the retains:
. the convention is that convenience methods are
using your autorelease pool .
. using the alloc init is your sign that
you own it (you need to auto/release it yourself )
. other than that, I've seen no intrinsic need for it;
... but, how does inheritance complicate things?
. it looks like the main reason is legacy code:
the Cocoa library can't maintain backward compatibility
unless you follow this convention .
. the main reason alloc was a class method,
was that init should be an instance method
but alloc (the source of the instance)
would have to be from a class method
because instance methods work on instances,
so the alloc couldn't be an instance method .
. I'm not sure whether {Buck, Yacktman} said that;
however, some oop evangelist did say that,
and I'd like to show next,
why I don't think it's true .
[1.31: 1.23:
. the usual oop idioms very much depend on
the root object being a pointer to heap node;
-- where that pointer that is the same size
across all objects --
and that pointer exists even before alloc is called .
. what the object really needs in order to have
access to some instance var's,
is to belong to some specific class;
and, it could get this either by
sending an init msg to the specific class it wants
or by letting the init's param decide on a class,
based upon the type of initial value assigned
(for example, when the compiler gets a value literal,
it can infer a type class from that:
"(abc) is a string
123 is a number
(1,2,3) is an array of number
(1, "(abc)) is a record in (number, string).
) . init figures out what it needs,
and then calls an alloc to help with that .
. if the client has a preference for some alloc technique
that could be a param of the init,
initWith (source, allocWith: style ) .]
Labels:
adda,
class cluster,
design patterns,
dev.obj'c,
oop,
type,
type class
a fraction calculator's interface without over.key
1.22: adde/math/handling fractions:
. the Kochan`Fractions Calculator has an over.key,
for allowing a fraction to be entered without eval'ing it;
another way to handle this
is to enter complex expressions:
nothing is eval'd until you hit enter,
so, expecting fractions, the only division happens when
there is the form a/b / c/d .
. also, the policy could be that
div's would be eval'd only when
they represent exact fractions:
eg, 2/5 is 2/5, while 1/2 is 0.5 [1.31:
that does present a problem with the base being decimal, 2*5
but the storage's base being binary?
you could have an exact fraction like 1/5 = 0.2 in base 10,
but that is a irrational number in base 2 .]
...
. even if it did eval each operator a.s.a.p.,
it could simply reduce and stay exact:
14/10 = 7/5 = (1+2/5).
. the Kochan`Fractions Calculator has an over.key,
for allowing a fraction to be entered without eval'ing it;
another way to handle this
is to enter complex expressions:
nothing is eval'd until you hit enter,
so, expecting fractions, the only division happens when
there is the form a/b / c/d .
. also, the policy could be that
div's would be eval'd only when
they represent exact fractions:
eg, 2/5 is 2/5, while 1/2 is 0.5 [1.31:
that does present a problem with the base being decimal, 2*5
but the storage's base being binary?
you could have an exact fraction like 1/5 = 0.2 in base 10,
but that is a irrational number in base 2 .]
...
. even if it did eval each operator a.s.a.p.,
it could simply reduce and stay exact:
14/10 = 7/5 = (1+2/5).
Objective-C Categories
1.20: adda/type/obj'c categories:
. Apple is using the obj'c Category for mvc separation;*
eg, string has many uses in a command-line interface,
so it exists in the core package
without any methods for drawing on a gui;
categories are then simply extending that string type,
instead of having sublclasses reuse that string type
in yet another type;
so just one class can exist yet with
relevant parts in different packages .
* see { Buck, Yacktman}`Cocoa Design Patterns
todo:
. isn't that use of categories needed only because
it's assuming something demanded by the current oop model?
. if your string wants to talk about gui-specific tricks
like font, or curve following,
that should be served by a drawing record
which then has a string as one of it's parts .
(ie, it's ok to have 2 diff'ing classes !)
--
that was a main point of the book"design patterns:
it was a critique of oop's use of subclassing;
and, that criticism can apply equally well to categorizing;
but, notice it does have a good purpose:
it allows separate compilation of extensions
without having to recompile the original interface
which would then require a recompile of
all the clients of that interface .
. but in this case, the category pattern is not needed,
the pattern to follow is this:
. the whole point of the mvc pattern is that
nearly all programming should be doable without having to
be aware of what your output device is .
. the same program I write for the command-line
should be apply without modification
to use by the gui-interfaced user .
. the runtime is supposed to have a default way of
visualizing your data structures graphically .
. the user is just another inout process
interacting with your process;
so, the gui should be handled by 2 generic packages:
it communicates with a concurrent process,
and then is also aware of 2-d or 3-d
placement preferences of datastruct's .
. so, how does adda let you define special effects
such as those specific to one style of gui?
eg, the curve-following text
needs a record (string, linedata),
and that record should have a particular name, say SL,
so then any var assigned the type SL
will be treated by the adda system as curve-following text
at least when dealing with the contexts
that are specified as customized by SL .
. the 2 primary contexts that work like that
are the user interface,
and the memory usage:
(persistent file, ram buffer, L1,2,3 cache).
. conversely,
when assigning an SL value to a native type,
then all gui-specific info would be dropped .
analysis of what it offers:
. the category has 2 use cases, depending on
whether you have the interface code,
or just have an interface document
that doesn't list the private ivars of the type .
. if you don't have the interface,
the diff' it makes seems purely syntactic:*
native functions can be stated oopishly: x`f();
and with categories you can start writing x`MYf() .
. that is offering more than just
adding a package whose input types are x`type:
the new package is being registered with the type,
so when I ask that type to apply a symbol named MYf,
the run-time engine is able to say it does .
. so, what is the equivalent to that
in lispy procedural (vs oop) programming?
. say the apply-operator is @,
I can then say ('f @ 'x) to mean f(x),
so that to apply dynamically any variable, X,
to any function, F,
I can write X`= 'x, F`= 'f, .... F @ X .
. it then looks to see if there exists a function f
that accepts x`type .
*: [1.31:
. even without affecting ivars,
the diff' it makes can be quite significant;
because, it can override methods that have
special systemic effects on the ivars,
and those effects will be missing .
. the oop syntax allows this:
x`f()`g()`h()
which means that x`f() returns an object x2
which, in turn, understands
what to do with g(), etc .
. so, the functional equivalent to x`f(...)`g(...)`h(...)
is h(g(f(x, ...), ... ), ...).
. that could mean the run-time is doing another check:
is there an f(x`type).y,
such that there is a function named g
that can accept y`type ?
. obj'c is not concerned with that though,
because once you assign a function to a particular type,
the run-time can quickly know to use
the function name f that is registered with that type .
. after that, it doesn't matter whether g can handle it;
because the object returned by x`type according to x`f
is offering no other choices .
. the reason obj'c does it this way
is for the other use case:
where the interface is known so then the
functions being added to x`type
need to register with x`type because
otherwise they won't be granted access to x`type's
private instance var's .
. this, then, is what obj'c categories uniquely do;
it's something like ada's child package feature .
. Apple is using the obj'c Category for mvc separation;*
eg, string has many uses in a command-line interface,
so it exists in the core package
without any methods for drawing on a gui;
categories are then simply extending that string type,
instead of having sublclasses reuse that string type
in yet another type;
so just one class can exist yet with
relevant parts in different packages .
* see { Buck, Yacktman}`Cocoa Design Patterns
todo:
. isn't that use of categories needed only because
it's assuming something demanded by the current oop model?
. if your string wants to talk about gui-specific tricks
like font, or curve following,
that should be served by a drawing record
which then has a string as one of it's parts .
(ie, it's ok to have 2 diff'ing classes !)
--
that was a main point of the book"design patterns:
it was a critique of oop's use of subclassing;
and, that criticism can apply equally well to categorizing;
but, notice it does have a good purpose:
it allows separate compilation of extensions
without having to recompile the original interface
which would then require a recompile of
all the clients of that interface .
. but in this case, the category pattern is not needed,
the pattern to follow is this:
. the whole point of the mvc pattern is that
nearly all programming should be doable without having to
be aware of what your output device is .
. the same program I write for the command-line
should be apply without modification
to use by the gui-interfaced user .
. the runtime is supposed to have a default way of
visualizing your data structures graphically .
. the user is just another inout process
interacting with your process;
so, the gui should be handled by 2 generic packages:
it communicates with a concurrent process,
and then is also aware of 2-d or 3-d
placement preferences of datastruct's .
. so, how does adda let you define special effects
such as those specific to one style of gui?
eg, the curve-following text
needs a record (string, linedata),
and that record should have a particular name, say SL,
so then any var assigned the type SL
will be treated by the adda system as curve-following text
at least when dealing with the contexts
that are specified as customized by SL .
. the 2 primary contexts that work like that
are the user interface,
and the memory usage:
(persistent file, ram buffer, L1,2,3 cache).
. conversely,
when assigning an SL value to a native type,
then all gui-specific info would be dropped .
analysis of what it offers:
. the category has 2 use cases, depending on
whether you have the interface code,
or just have an interface document
that doesn't list the private ivars of the type .
. if you don't have the interface,
the diff' it makes seems purely syntactic:*
native functions can be stated oopishly: x`f();
and with categories you can start writing x`MYf() .
. that is offering more than just
adding a package whose input types are x`type:
the new package is being registered with the type,
so when I ask that type to apply a symbol named MYf,
the run-time engine is able to say it does .
. so, what is the equivalent to that
in lispy procedural (vs oop) programming?
. say the apply-operator is @,
I can then say ('f @ 'x) to mean f(x),
so that to apply dynamically any variable, X,
to any function, F,
I can write X`= 'x, F`= 'f, .... F @ X .
. it then looks to see if there exists a function f
that accepts x`type .
*: [1.31:
. even without affecting ivars,
the diff' it makes can be quite significant;
because, it can override methods that have
special systemic effects on the ivars,
and those effects will be missing .
. the oop syntax allows this:
x`f()`g()`h()
which means that x`f() returns an object x2
which, in turn, understands
what to do with g(), etc .
. so, the functional equivalent to x`f(...)`g(...)`h(...)
is h(g(f(x, ...), ... ), ...).
. that could mean the run-time is doing another check:
is there an f(x`type).y,
such that there is a function named g
that can accept y`type ?
. obj'c is not concerned with that though,
because once you assign a function to a particular type,
the run-time can quickly know to use
the function name f that is registered with that type .
. after that, it doesn't matter whether g can handle it;
because the object returned by x`type according to x`f
is offering no other choices .
. the reason obj'c does it this way
is for the other use case:
where the interface is known so then the
functions being added to x`type
need to register with x`type because
otherwise they won't be granted access to x`type's
private instance var's .
. this, then, is what obj'c categories uniquely do;
it's something like ada's child package feature .
large trees composed of byte-ptr trees
1.8: adda/mem'mgt/
large trees composed of byte-ptr trees:
. part of a space-saving obssession has been
finding how to make large trees be composed of
small trees that can use byte-sized pointers .
. the large tree is just like the local heap space:
a function activation record is given one segment
in which to store local data and param's;
after that fills up, it's turned into rib of a backbone segment:
(an array of c pointers to other segs).
. the way this is arranged should be such that
we can refer to the rib segs as indexes of the base seg,
. if all those fill up, then the last seg is the next size up:
. say the backbone hold 10ribs of size 10,
then the last rib is 10x10 size.
...
. isn't this supposed to be building the same way numbers do?
after the backbone fills up, it needs to be extended from above;
ie, replace the seg tree with a new backbone seg,
and then make the full backbone seg
a child of the new backbone seg:
====
|
====
| | | | | .
1.23: adda/type"tree/packing smaller trees:
. you can build a tree in large array
and if detecting under 255,
do a straight copy to small: for 1..256: copy word to byte
because the same links apply using the same structure
only smaller pointers .
large trees composed of byte-ptr trees:
. part of a space-saving obssession has been
finding how to make large trees be composed of
small trees that can use byte-sized pointers .
. the large tree is just like the local heap space:
a function activation record is given one segment
in which to store local data and param's;
after that fills up, it's turned into rib of a backbone segment:
(an array of c pointers to other segs).
. the way this is arranged should be such that
we can refer to the rib segs as indexes of the base seg,
. if all those fill up, then the last seg is the next size up:
. say the backbone hold 10ribs of size 10,
then the last rib is 10x10 size.
...
. isn't this supposed to be building the same way numbers do?
after the backbone fills up, it needs to be extended from above;
ie, replace the seg tree with a new backbone seg,
and then make the full backbone seg
a child of the new backbone seg:
====
|
====
| | | | | .
1.23: adda/type"tree/packing smaller trees:
. you can build a tree in large array
and if detecting under 255,
do a straight copy to small: for 1..256: copy word to byte
because the same links apply using the same structure
only smaller pointers .
wild vs proper goto's vs informal looping
1.6: adda/cstr/goto:
. if goto's are jumping high in same the block
the place they jump to need only be typed .loop,
but wild jumps need to be typed .<<>>
. when used at the end to break from a nested cstr,
the goto is a clean jump to bottom,
these are typed .exit? [1.31:
no:
. this is the proper use of goto;
so, it doesn't need a special type,
but every thing should have a type,
and the default type for labels could be .label .]
. to enter wrapup.label
use the syntax (enter wrapup) ? [1.31:
yes .]
. don't use the syntax (exit);
because, it may not be to exit self*
and (exit (current enclosure)) should be reserved for
situations that actually involve
jumping out of some enclosing container .
*:
. the other exits are {main, parent, thread}
as well as named cstr's {case, loop }.
. at each cstr (any structure that may contain stmts)
there can be a wrapup section named [on exit];
on().proc can also concurrently check
any number of conditions that implicitely
call the given responder routine when the guard is true . [1.31:
eg, on mem-out: (save work; log error) .]
. if goto's are jumping high in same the block
the place they jump to need only be typed .loop,
but wild jumps need to be typed .<<>>
. when used at the end to break from a nested cstr,
the goto is a clean jump to bottom,
these are typed .exit? [1.31:
no:
. this is the proper use of goto;
so, it doesn't need a special type,
but every thing should have a type,
and the default type for labels could be .label .]
. to enter wrapup.label
use the syntax (enter wrapup) ? [1.31:
yes .]
. don't use the syntax (exit);
because, it may not be to exit self*
and (exit (current enclosure)) should be reserved for
situations that actually involve
jumping out of some enclosing container .
*:
. the other exits are {main, parent, thread}
as well as named cstr's {case, loop }.
. at each cstr (any structure that may contain stmts)
there can be a wrapup section named [on exit];
on().proc can also concurrently check
any number of conditions that implicitely
call the given responder routine when the guard is true . [1.31:
eg, on mem-out: (save work; log error) .]
Labels:
adda,
cstr,
enclosures,
goto
variable case ranges
1.5: adda/cstr/case/variable case ranges:
. if the cases can be variable expressions
how does that work? how useful is that?
it does seem to suit a parallel case,
which would entail this equivalence:
e? # a: ;;; # b: ;;; # c: ;;; #; <=>
eval'd in parallel:
{ e= a? (;;;)
, e= b? (;;;)
, e= c? (;;;)
}
. the general characteristic required for
a non-parallel case stmt
is that it select no more than one of the
alternative execution paths .
. one useful example of variable case ranges
is when the use of variables and simple arithmetic
still provide a partition of the codomain,
ie, none of the case ranges are overlapping;
eg,
here are examples of simply shifting
the location of the boundaries between
exec'path guard partitions:
reals from a..d can vary to effect the outcome
of the following case .
e ?
#[a...b): proc1;
#[b...c): proc2;
#[c...d]: proc3 #;
and likewise for these variable integer ranges:
{a..b}, {b+1..c}, {c+1..d} .
. another use of such arithmetic
would provide case-range restrictions,
so that a varying set of cases are going to
the {others, do-nothing} execution paths .
. if the cases can be variable expressions
how does that work? how useful is that?
it does seem to suit a parallel case,
which would entail this equivalence:
e? # a: ;;; # b: ;;; # c: ;;; #; <=>
eval'd in parallel:
{ e= a? (;;;)
, e= b? (;;;)
, e= c? (;;;)
}
. the general characteristic required for
a non-parallel case stmt
is that it select no more than one of the
alternative execution paths .
. one useful example of variable case ranges
is when the use of variables and simple arithmetic
still provide a partition of the codomain,
ie, none of the case ranges are overlapping;
eg,
here are examples of simply shifting
the location of the boundaries between
exec'path guard partitions:
reals from a..d can vary to effect the outcome
of the following case .
e ?
#[a...b): proc1;
#[b...c): proc2;
#[c...d]: proc3 #;
and likewise for these variable integer ranges:
{a..b}, {b+1..c}, {c+1..d} .
. another use of such arithmetic
would provide case-range restrictions,
so that a varying set of cases are going to
the {others, do-nothing} execution paths .
parsing unmatching opening characters
1.5: adda/parse/algorithm for parsing containers:
. there can be non-matching container parts,
because they can be surounded by complete containers,
eg, ( ... [ ...{} ),
. the recursive way is this:
find an opening to some container,
and then call the function that reads that container;
what else that function will need, though,
is knowing whether it was sent by
another container-reading function;
so, in the example above, ( ... [ ...{} ),
getParen is calling getBracket( ")" ),
so then getBracket knows it needs to be stopping for
both {")", "]"}, whichever come first .
. if getBracket returns nil,
then getParen will know that the "[" should be taken as
a character, not the beginning of a subtree .
. any 3rd possibility?
no, but it does involve recursive backtracking,
with multiple readers on a single stream: [1.31:
. both caller and called could
fail to find their closing match .
. then to not have to do work over again,
it should have some way remembering
whether a given opening character has a match .
. another needed dimension is being fault tolerant:
if the coder forgot a closing character,
then there should be other ways of parsing
that will be able to guess something is missing;
eg, a line has found an new function definition
in the middle of a function body,
it could guess that the body above is
missing a closing character .]
. there can be non-matching container parts,
because they can be surounded by complete containers,
eg, ( ... [ ...{} ),
. the recursive way is this:
find an opening to some container,
and then call the function that reads that container;
what else that function will need, though,
is knowing whether it was sent by
another container-reading function;
so, in the example above, ( ... [ ...{} ),
getParen is calling getBracket( ")" ),
so then getBracket knows it needs to be stopping for
both {")", "]"}, whichever come first .
. if getBracket returns nil,
then getParen will know that the "[" should be taken as
a character, not the beginning of a subtree .
. any 3rd possibility?
no, but it does involve recursive backtracking,
with multiple readers on a single stream: [1.31:
. both caller and called could
fail to find their closing match .
. then to not have to do work over again,
it should have some way remembering
whether a given opening character has a match .
. another needed dimension is being fault tolerant:
if the coder forgot a closing character,
then there should be other ways of parsing
that will be able to guess something is missing;
eg, a line has found an new function definition
in the middle of a function body,
it could guess that the body above is
missing a closing character .]
Labels:
adda,
enclosures,
parse
inout-mode parameters
1.4: adda/syntax/{inout, out}-mode parameters:
. {inout, out}-mode parameters are special because
they create sideaffects .
[1.6:
. anyone coming from any other language
will be assuming that if you pass a pointer
then it means you get to modify
anything accessable by that pointer;
-- that is the whole point of pointers,
unless their targets are typed as being read-only mode;
however,
other languages have created a lot of bugs too,
so we really should carefully reconsider
designing our functions to be functional by default .
1.7:
. the usual understanding of aParam typed as
pointer to int is read-only pointer to inout int;
whereas, what we are assuming here is
read-only pointer to read-only int .
. the usual understanding of an
inout param typed as pointer to int is
inout pointer to inout int;
whereas, what we are assuming here is
inout pointer to read-only int .]
. the Ada goto label was chosen as notation that alarms,
and that's why I had chosen it for out-moding params;
the param x, a pointer to int,
out-moding on both the pointer and the int; [1.6:
however, something similar and easier to read is (^);
will it be confused with the power operator?
if it's placed at the back of the typemark,
then it clearly gives a context to reader and parser .]
. the most elegant way to define inout mode
is to unify it with its implied activity: inititialization .
. param's can specify default init values,
and if that init is the param' being defined,
that would imply inout mode
while doing something else essential . [1.6:
. however,
it seems counter to the intended model,
because defaults are supposed to tell you
what happens when you fail to supply the actual param,
implying that it's optional,
by contrast, what we're trying to say is:
not only is the param' instantiation not optional,
but the actual param's initial value is not optional either;
so, another idea is to precede the (out)-symbol
with an (in)-symbol such as (&);
since the default is in-mode,
and t^ means t is out-mode,
so t&^ would say t is in-mode & out-mode .
. if that seems like a stretch, then how about t'^ ?
the apostrophe seems like an arrow pointing down,
while the caret is arrow pointing up,
hence an iconic representation of inout;
and being on the back side of types,
it would fit in with the proposed typemark for
rom (read-only mem): t! .]-1.6
. when types contain types,
as in /.int (the type"pointer to int)
we need a notation to specify
which of those types can be modified;
therefore we can not
simply apply the notation to the parameter name,
as is done in other languages .
[1.7:
. we can provide that as an option though;
eg # inout aParam/.int!
--. this provides read-write access to
a pointer to a read-only int
(same as our aParam/'^.int);
eg # inout aParam/!.int
-- read-only access to a pointer to a read&writable int
(same as aParam/.int'^).]
[1.6:
. notice that, among container types such as
/.int (a pointer.type containing the int.type)
if you don't need the value of a param
(and are thus giving it the attribute out-mode),
you certainly don't need the values of any type within;
eg, /^.int'^ wouldn't make sense because
how can there be a value to get from the int
when there no value expected from
the pointer that is needed to access the int?
. if something like "(/^.int'^ )
could never make sense to some users anyway,
they should be allowed to use simple english too:
{out, inout } -- copy is the default .
. inout-mode could be understood to be
a property possessed by a type,
hence the use of the possessive operator:
/'^.int^ becomes /`inout.int`out (read:
pointer's inout to int's out ).
. another idea is that
{out, inout} would be functions over types,
so instead of needing a possessive operator,
you could simply use a space:
x/'^.int^ becomes x.inout /.out int .
. in this case, {inout, out} need to be reserved words?
we could allow renaming them,
eg, {o, io} or {wo, rw} might be popular .]-1.6
[1.6:
. by letting {out, inout} be a function,
it would also make sense to do it Ada's way:
letting the inout apply to the param itself,
instead of applying to each of the param's nested types;
eg,
inout x/.int -- just give me inout everything!
. why do you suppose Ada doesn't facilitate
applying {inout, out} to each of the param's
nested types?
[1.7: besides the fact that it's param's can
only trivially be container types
(you need to use a single type name
or a pointer to typename)]
. perhaps they are mostly concerned with
a transaction model:
this is where the implementation of out-mode
has the option of either using a reference,
or else doing a copy-in then copy-out .
. doing it my way could save much copying,
because suppose you have a pointer to a huge tree;
if all you want to do is modify the pointer,
then the copy-in©-out system
doesn't have to copy that huge tree for you! ]-1.6
1.7: web: ada parameters:
. Ada's rationale for not supporting pass-by-reference:
{. parameter passing by reference for access types
is not expected by most algorithms and will result in
those algorithms being incorrect .}
. access types are already unique in that the programmer is
permitted explicitly to manipulate references and construct aliases:
This is the purpose of access types,
and programmers using such types are asserting that
they wish to take control of all references and aliases.
Accordingly, the parameter passing should not generate
extra references and aliases of which the programmer is unaware;
therefore, all parameter passing for access types
should be by copy.
A final problem with parameter passing by reference
is that this mechanism will be almost impossible to achieve
(or at least, very costly) on distributed systems
and when dealing with systems having multiple address spaces.
--
. but the 2012 version does support them .
ada parameters/syntax:
2005 parameter_specification ::=
defining_identifier_list : mode [null_exclusion]
subtype_mark [:= default_expression]
| defining_identifier_list : access_definition
[:= default_expression]
2012 parameter_specification ::=
defining_identifier_list : [aliased] mode [null_exclusion]
subtype_mark [:= default_expression]
| defining_identifier_list : access_definition
[:= default_expression]
access_definition ::=
[null_exclusion] access [constant] subtype_mark
| [null_exclusion] access [protected]
procedure parameter_profile
| [null_exclusion] access [protected]
function parameter_and_result_profile access subtype_mark
. {inout, out}-mode parameters are special because
they create sideaffects .
[1.6:
. anyone coming from any other language
will be assuming that if you pass a pointer
then it means you get to modify
anything accessable by that pointer;
-- that is the whole point of pointers,
unless their targets are typed as being read-only mode;
however,
other languages have created a lot of bugs too,
so we really should carefully reconsider
designing our functions to be functional by default .
1.7:
. the usual understanding of aParam typed as
pointer to int is read-only pointer to inout int;
whereas, what we are assuming here is
read-only pointer to read-only int .
. the usual understanding of an
inout param typed as pointer to int is
inout pointer to inout int;
whereas, what we are assuming here is
inout pointer to read-only int .]
. the Ada goto label was chosen as notation that alarms,
and that's why I had chosen it for out-moding params;
eg, x<</.int>> would be used for havingthe param x, a pointer to int,
out-moding on both the pointer and the int; [1.6:
however, something similar and easier to read is (^);
will it be confused with the power operator?
if it's placed at the back of the typemark,
then it clearly gives a context to reader and parser .]
. the most elegant way to define inout mode
is to unify it with its implied activity: inititialization .
. param's can specify default init values,
and if that init is the param' being defined,
that would imply inout mode
while doing something else essential . [1.6:
. however,
it seems counter to the intended model,
because defaults are supposed to tell you
what happens when you fail to supply the actual param,
implying that it's optional,
by contrast, what we're trying to say is:
not only is the param' instantiation not optional,
but the actual param's initial value is not optional either;
so, another idea is to precede the (out)-symbol
with an (in)-symbol such as (&);
since the default is in-mode,
and t^ means t is out-mode,
so t&^ would say t is in-mode & out-mode .
. if that seems like a stretch, then how about t'^ ?
the apostrophe seems like an arrow pointing down,
while the caret is arrow pointing up,
hence an iconic representation of inout;
and being on the back side of types,
it would fit in with the proposed typemark for
rom (read-only mem): t! .]-1.6
. when types contain types,
as in /.int (the type"pointer to int)
we need a notation to specify
which of those types can be modified;
therefore we can not
simply apply the notation to the parameter name,
as is done in other languages .
[1.7:
. we can provide that as an option though;
eg # inout aParam/.int!
--. this provides read-write access to
a pointer to a read-only int
(same as our aParam/'^.int);
eg # inout aParam/!.int
-- read-only access to a pointer to a read&writable int
(same as aParam/.int'^).]
[1.6:
. notice that, among container types such as
/.int (a pointer.type containing the int.type)
if you don't need the value of a param
(and are thus giving it the attribute out-mode),
you certainly don't need the values of any type within;
eg, /^.int'^ wouldn't make sense because
how can there be a value to get from the int
when there no value expected from
the pointer that is needed to access the int?
. if something like "(/^.int'^ )
could never make sense to some users anyway,
they should be allowed to use simple english too:
{out, inout } -- copy is the default .
. inout-mode could be understood to be
a property possessed by a type,
hence the use of the possessive operator:
/'^.int^ becomes /`inout.int`out (read:
pointer's inout to int's out ).
. another idea is that
{out, inout} would be functions over types,
so instead of needing a possessive operator,
you could simply use a space:
x/'^.int^ becomes x.inout /.out int .
. in this case, {inout, out} need to be reserved words?
we could allow renaming them,
eg, {o, io} or {wo, rw} might be popular .]-1.6
[1.6:
. by letting {out, inout} be a function,
it would also make sense to do it Ada's way:
letting the inout apply to the param itself,
instead of applying to each of the param's nested types;
eg,
inout x/.int -- just give me inout everything!
. why do you suppose Ada doesn't facilitate
applying {inout, out} to each of the param's
nested types?
[1.7: besides the fact that it's param's can
only trivially be container types
(you need to use a single type name
or a pointer to typename)]
. perhaps they are mostly concerned with
a transaction model:
this is where the implementation of out-mode
has the option of either using a reference,
or else doing a copy-in then copy-out .
. doing it my way could save much copying,
because suppose you have a pointer to a huge tree;
if all you want to do is modify the pointer,
then the copy-in©-out system
doesn't have to copy that huge tree for you! ]-1.6
1.7: web: ada parameters:
. Ada's rationale for not supporting pass-by-reference:
{. parameter passing by reference for access types
is not expected by most algorithms and will result in
those algorithms being incorrect .}
. access types are already unique in that the programmer is
permitted explicitly to manipulate references and construct aliases:
This is the purpose of access types,
and programmers using such types are asserting that
they wish to take control of all references and aliases.
Accordingly, the parameter passing should not generate
extra references and aliases of which the programmer is unaware;
therefore, all parameter passing for access types
should be by copy.
A final problem with parameter passing by reference
is that this mechanism will be almost impossible to achieve
(or at least, very costly) on distributed systems
and when dealing with systems having multiple address spaces.
--
. but the 2012 version does support them .
ada parameters/syntax:
2005 parameter_specification ::=
defining_identifier_list : mode [null_exclusion]
subtype_mark [:= default_expression]
| defining_identifier_list : access_definition
[:= default_expression]
2012 parameter_specification ::=
defining_identifier_list : [aliased] mode [null_exclusion]
subtype_mark [:= default_expression]
| defining_identifier_list : access_definition
[:= default_expression]
access_definition ::=
[null_exclusion] access [constant] subtype_mark
| [null_exclusion] access [protected]
procedure parameter_profile
| [null_exclusion] access [protected]
function parameter_and_result_profile access subtype_mark
Labels:
1st-class functions,
adda,
syntax,
type
generic type vs container type
1.4: adda/type/{generic, container}-type def's:
. there is a syntax for parametric types generally,
with multiple params that include
both types and non-types ? yes:
[1.6:
. the parameterized type is a sort of generic;
so, there are 2 points at which it is instantiated:
once to define the concrete type,
and then again for each use of that concrete type
in defining an obj' instance .
. to distinguish these,
use the terms {generic, container}-type .
. the {array, pointer} are really containers;
on the way to defining more container types,
you can use a generic type
which then must be instantiated
before use by container obj's .
. a container type could accept a record type as its leaf;
then each of those record fields
could be instantiations of a generic-type
that could return a container-type .
. the generic-types should not need
separate instantiation:
[1.7: eg,
( myLeafType.type: gentype(init)
; x.myLeafType; )
can also be done as x.gentype(init) .]
. here's a combination of generic and container instantiations
in one term:
pointertype(inits for variant selection).myLeafType .
. arrays, pointers, and functions are container types;
how are new container types defined ?
. recall that pointers and arrays are
types of functions [expressing container types]
but, can new [container] types be
defined like functions without confusion ?
yes:
. a function where the arg is of type .type;
eg, pointer.type is defined as:
/(type).type;
this works with these rules:
(1) function args are not required to be paren'd,
(2) types are preceded by a dot:
/.txt = /(.txt).
. there is a syntax for parametric types generally,
with multiple params that include
both types and non-types ? yes:
[1.6:
. the parameterized type is a sort of generic;
so, there are 2 points at which it is instantiated:
once to define the concrete type,
and then again for each use of that concrete type
in defining an obj' instance .
. to distinguish these,
use the terms {generic, container}-type .
. the {array, pointer} are really containers;
on the way to defining more container types,
you can use a generic type
which then must be instantiated
before use by container obj's .
. a container type could accept a record type as its leaf;
then each of those record fields
could be instantiations of a generic-type
that could return a container-type .
. the generic-types should not need
separate instantiation:
[1.7: eg,
( myLeafType.type: gentype(init)
; x.myLeafType; )
can also be done as x.gentype(init) .]
. here's a combination of generic and container instantiations
in one term:
pointertype(inits for variant selection).myLeafType .
. arrays, pointers, and functions are container types;
how are new container types defined ?
. recall that pointers and arrays are
types of functions [expressing container types]
but, can new [container] types be
defined like functions without confusion ?
yes:
. a function where the arg is of type .type;
eg, pointer.type is defined as:
/(type).type;
this works with these rules:
(1) function args are not required to be paren'd,
(2) types are preceded by a dot:
/.txt = /(.txt).
Labels:
1st-class functions,
adda,
generics,
type
adda minimizes paretheses
1.3: adda/syntax/lists of algorithm literals:
. the comma-semicolon syntax for lists
( ,,, ; ,,,,, ; ,,, ) would be confused with
those of an algorithm literal,
( ,,,: ; ;;; ,,,:; ;;; )
unless the algorithm literal is parenthesized;
( ,,, ; ,,( ,,,: ; ;;; ,,,:; ;;; ), ; ,,, )
that should be a general requirement
with the exception that
a file already constitutes a parenthesis .
[1.6: (interactive mode is a type of streamed file;
and adding the paren's would supress execution
until the closing paren' was added) .]
. with that requirement in place,
I can feel more confident designing
subprogram calls without paren's
[@] adda/syntax/subprogram calls without paren's
adda/syntax/
subprogram calls without paren's
. one thing I was taught by lisp counter/zealotry
is that if a language is to have
any chance of being popular
it should go out of its way to
avoid excessive parentheses!
. any symbol that is declared as a function
and is found in a sequence of statements,
can use the form: f x,y,z;
instead of f(x,y,z) .
. if you have: f g x,y;
that should be parsed as f(g(x,y)) ?
at least according to the
nested-if rule:
(if * then if * then * else *)
-- that would be parsed
like so:
if * then (if * then * else *)
rather than:
if * then (if * then * ) else * .
. but what does that do for the rule about
lists requiring paren's when nested in lists?
[@] adda/syntax/lists of algorithm literals
. moot: a unary arg is not a list .
. the comma-semicolon syntax for lists
( ,,, ; ,,,,, ; ,,, ) would be confused with
those of an algorithm literal,
( ,,,: ; ;;; ,,,:; ;;; )
unless the algorithm literal is parenthesized;
( ,,, ; ,,( ,,,: ; ;;; ,,,:; ;;; ), ; ,,, )
that should be a general requirement
with the exception that
a file already constitutes a parenthesis .
[1.6: (interactive mode is a type of streamed file;
and adding the paren's would supress execution
until the closing paren' was added) .]
. with that requirement in place,
I can feel more confident designing
subprogram calls without paren's
[@] adda/syntax/subprogram calls without paren's
adda/syntax/
subprogram calls without paren's
. one thing I was taught by lisp counter/zealotry
is that if a language is to have
any chance of being popular
it should go out of its way to
avoid excessive parentheses!
. any symbol that is declared as a function
and is found in a sequence of statements,
can use the form: f x,y,z;
instead of f(x,y,z) .
. if you have: f g x,y;
that should be parsed as f(g(x,y)) ?
at least according to the
nested-if rule:
(if * then if * then * else *)
-- that would be parsed
like so:
if * then (if * then * else *)
rather than:
if * then (if * then * ) else * .
. but what does that do for the rule about
lists requiring paren's when nested in lists?
[@] adda/syntax/lists of algorithm literals
. moot: a unary arg is not a list .
Labels:
1st-class functions,
adda,
cstr,
syntax
adda's case stmt evolves
1.2: adda/cstr/case/
similar to goto labels not function points list:
[1.5: intro:
. the case stmt was seen to share the same structure as
that of the param'list, record'literal,
and the function points list:
( domain-elements,,,: codomain-element
, d,d,d,d: cod
) -- if a domain element is followed by a comma,
then it's part of a list of domain elements
all sharing the same codomain element .
. however,
the colon character is also used for identifying address labels:
( label,,,: ; ;;;
label:
...)
-- the c lang's fall-through case stmt has similar syntax
in that it's reusing label syntax * .
. the case doesn't need commas like the function points list;
because, it can work like other labels; [1.31:
(the case stmt does still use commas for the domain lists;
ie, for when multiple cases having the same target ).]
. the usual (;) vs (,) priority is exemplified by the matrix, eg:
( el, el, el,
; el, el, el,
; el, el, el ),
[1.31: this is contrast to the list of statement's
in which declaration stmt's use commas in the domain list:
( v1, v2, v3: shared-type
; v1, v2, v3: shared-type
; stmt; stmt; stmt
);]
. a case list (the list of control paths being offered)
has elements that include sequences (of stmt's);
so, we have to make sure that the context always tells us
which situation you're going into:
a list of lists, (as seen in a matrix) versus
a list of sequences .
. if a sequence of stmts is an element in matrix
it creates ambiguity if unparenthesized:
(,,,
; ,,, ;;; ,
; ,,,
) .
*: [1.31:
. actually, a key feature of c's case syntax,
is the case-prefixing used within the body-container of
switch ( expression ) body-container:
switch ( expression )
{ declaration stmts ;;; -- adda instead has inline decl's .
case a: -- the case label is like a stmt but terminated by (:);
case b: stmt; stmt; -- a's and b's target stmts .
default: stmt .
} .
. the adda case stmt differs from c's in that
it is like its other conditional stmt (the if):
truth ? stmt else stmt; -- the if-else;
truth ? #true: stmt; #false: stmt; #; -- the case .
. like c, however, adda tries to minimize syntax;
and, towards that end,
notice the cases wouldn't need paren's around them if
the final case keyword was followed by the (;);
conversely, the (#.) is not needed if
the case stmt or its body are in paren's;
however, always having a case-terminal at the end of case
might help syntax errors involving enclosures;
or else it could be thought of as a type of enclosure:
( ,,, ; ,,, ; ,,, . ,,, ; ,,, ; ,,, ) -- for the data
#a: s;s;s; #b: s;s;s; #; -- for the cases .
. if preferring english over symbols, (case) = (#):
truth ?
case true: stmt;
case false: stmt;
case; ]-1.31
1.2: adda/cstr/case/
supporting c's fall-through style:
. should the case like c's be called fallthru?
how could it be called jmp or goto?
it should include the usual syntax shared by
all conditional stmt's .
[... but that syntax is about to change:]
[@] adda/cstr/case/similar to goto labels not function points list
fallthru e ? (e, ,,, : s; s; s; e,,,: s;;; );
--
. the inside of a case stmt looks just like a stmt block .
. fallthru is a control function of 1 arg:
fallthru(case.stmt).stmt;
it expects its arg to be a case stmt .
1.5: inverting the default:
. a more intuitive use of the fallthru keyword
would be to have it used for
meaning just the opposite of the c lang's break stmt:
. when you wanted to fall-through,
then the fallthru stmt would be used to override
the default behavior .
1.5: minimize reserved words:
. instead of fallthru as a keyword
it might be better to reuse what we have,
such as (enter next),
-- "(next) doesn't have to be a reserved word,
because it's still local to the arg of function"enter --
or generalize it like this: [1.8:
enter case [some label within the case stmt] ].
adda/cstr/case/
only fallthru's need an exit stmt:
1.2:
. in a fallthru, the break is called exit,
just as in the loops,
when loops and case stmts are nested
you can specify where you want to exit to:
ie, "(exit loop) vs "(exit fallthru) .
. if it's a normal (non-fallthru) case stmt,
then there is no need for an exit stmt
so mentioning exit
would apply to a surrounding loop or fallthru .
1.5: not true:
. that's actually debatable;
because, a case could want to bail out early?;
conversely,
while an exit may be useful for some,
it could be inconvenient for many,
as it is very common have a case within a loop,
so if the case's use of exit could apply to itself
instead of the surrounding loop,
then that use of the exit stmt would have to specify
whether it referred to the {case stmt, loop stmt},
and the default target for an exit from a case stmt
would intuitively be exit case,
whereas in most cases the exit loop was desired;
then again,
it would be simpler, and more readable,
to have no default,
and then you could let coders have maximal freedom,
exiting anything from anywhere .
. furthermore,
even fall-through case stmts rarely do a fall-through;
they usually have more break stmt's than not;
so, the default behavior at the end of a case (case.stmt`branch)
should be (exit case) rather than (fallthru)
and if you mean otherwise, use an (enter next case).stmt
only at the end of the particular case
that needs to fall through .
1.2: adda/cstr/case/
supporting c's fall-through style:
. should the case like c's be called fallthru?
how could it be called jmp or goto?
it should include the usual syntax shared by
all conditional stmt's .
[... but that syntax is about to change:]
[@] adda/cstr/case/similar to goto labels not function points list
fallthru e ? (e, ,,, : s; s; s; e,,,: s;;; );
--
. the inside of a case stmt looks just like a stmt block .
. fallthru is a control function of 1 arg:
fallthru(case.stmt).stmt;
it expects its arg to be a case stmt .
1.5: inverting the default:
. a more intuitive use of the fallthru keyword
would be to have it used for
meaning just the opposite of the c lang's break stmt:
. when you wanted to fall-through,
then the fallthru stmt would be used to override
the default behavior .
1.5: minimize reserved words:
. instead of fallthru as a keyword
it might be better to reuse what we have,
such as (enter next),
-- "(next) doesn't have to be a reserved word,
because it's still local to the arg of function"enter --
or generalize it like this: [1.8:
enter case [some label within the case stmt] ].
adda/cstr/case/
the cases need not be literals:
1.2:
. whether the labels need to be const's,
being enums they eval to self,
so generally the case guard can always be eval'd;
you can also use expressions as literal cases
by quoting them, which supresses eval;
in that case,
the expr being cased should eval to etree;
because, a quoted expression is always an etree .
similar to goto labels not function points list:
[1.5: intro:
. the case stmt was seen to share the same structure as
that of the param'list, record'literal,
and the function points list:
( domain-elements,,,: codomain-element
, d,d,d,d: cod
) -- if a domain element is followed by a comma,
then it's part of a list of domain elements
all sharing the same codomain element .
. however,
the colon character is also used for identifying address labels:
( label,,,: ; ;;;
label:
...)
-- the c lang's fall-through case stmt has similar syntax
in that it's reusing label syntax * .
. the case doesn't need commas like the function points list;
because, it can work like other labels; [1.31:
(the case stmt does still use commas for the domain lists;
ie, for when multiple cases having the same target ).]
. the usual (;) vs (,) priority is exemplified by the matrix, eg:
( el, el, el,
; el, el, el,
; el, el, el ),
[1.31: this is contrast to the list of statement's
in which declaration stmt's use commas in the domain list:
( v1, v2, v3: shared-type
; v1, v2, v3: shared-type
; stmt; stmt; stmt
);]
. a case list (the list of control paths being offered)
has elements that include sequences (of stmt's);
so, we have to make sure that the context always tells us
which situation you're going into:
a list of lists, (as seen in a matrix) versus
a list of sequences .
. if a sequence of stmts is an element in matrix
it creates ambiguity if unparenthesized:
(,,,
; ,,, ;;; ,
; ,,,
) .
*: [1.31:
. actually, a key feature of c's case syntax,
is the case-prefixing used within the body-container of
switch ( expression ) body-container:
switch ( expression )
{ declaration stmts ;;; -- adda instead has inline decl's .
case a: -- the case label is like a stmt but terminated by (:);
case b: stmt; stmt; -- a's and b's target stmts .
default: stmt .
} .
. the adda case stmt differs from c's in that
it is like its other conditional stmt (the if):
truth ? stmt else stmt; -- the if-else;
truth ? #true: stmt; #false: stmt; #; -- the case .
. like c, however, adda tries to minimize syntax;
and, towards that end,
notice the cases wouldn't need paren's around them if
the final case keyword was followed by the (;);
conversely, the (#.) is not needed if
the case stmt or its body are in paren's;
however, always having a case-terminal at the end of case
might help syntax errors involving enclosures;
or else it could be thought of as a type of enclosure:
( ,,, ; ,,, ; ,,, . ,,, ; ,,, ; ,,, ) -- for the data
#a: s;s;s; #b: s;s;s; #; -- for the cases .
. if preferring english over symbols, (case) = (#):
truth ?
case true: stmt;
case false: stmt;
case; ]-1.31
1.2: adda/cstr/case/
supporting c's fall-through style:
. should the case like c's be called fallthru?
how could it be called jmp or goto?
it should include the usual syntax shared by
all conditional stmt's .
[... but that syntax is about to change:]
[@] adda/cstr/case/similar to goto labels not function points list
fallthru e ? (e, ,,, : s; s; s; e,,,: s;;; );
--
. the inside of a case stmt looks just like a stmt block .
. fallthru is a control function of 1 arg:
fallthru(case.stmt).stmt;
it expects its arg to be a case stmt .
1.5: inverting the default:
. a more intuitive use of the fallthru keyword
would be to have it used for
meaning just the opposite of the c lang's break stmt:
. when you wanted to fall-through,
then the fallthru stmt would be used to override
the default behavior .
1.5: minimize reserved words:
. instead of fallthru as a keyword
it might be better to reuse what we have,
such as (enter next),
-- "(next) doesn't have to be a reserved word,
because it's still local to the arg of function"enter --
or generalize it like this: [1.8:
enter case [some label within the case stmt] ].
adda/cstr/case/
only fallthru's need an exit stmt:
1.2:
. in a fallthru, the break is called exit,
just as in the loops,
when loops and case stmts are nested
you can specify where you want to exit to:
ie, "(exit loop) vs "(exit fallthru) .
. if it's a normal (non-fallthru) case stmt,
then there is no need for an exit stmt
so mentioning exit
would apply to a surrounding loop or fallthru .
1.5: not true:
. that's actually debatable;
because, a case could want to bail out early?;
conversely,
while an exit may be useful for some,
it could be inconvenient for many,
as it is very common have a case within a loop,
so if the case's use of exit could apply to itself
instead of the surrounding loop,
then that use of the exit stmt would have to specify
whether it referred to the {case stmt, loop stmt},
and the default target for an exit from a case stmt
would intuitively be exit case,
whereas in most cases the exit loop was desired;
then again,
it would be simpler, and more readable,
to have no default,
and then you could let coders have maximal freedom,
exiting anything from anywhere .
. furthermore,
even fall-through case stmts rarely do a fall-through;
they usually have more break stmt's than not;
so, the default behavior at the end of a case (case.stmt`branch)
should be (exit case) rather than (fallthru)
and if you mean otherwise, use an (enter next case).stmt
only at the end of the particular case
that needs to fall through .
1.2: adda/cstr/case/
supporting c's fall-through style:
. should the case like c's be called fallthru?
how could it be called jmp or goto?
it should include the usual syntax shared by
all conditional stmt's .
[... but that syntax is about to change:]
[@] adda/cstr/case/similar to goto labels not function points list
fallthru e ? (e, ,,, : s; s; s; e,,,: s;;; );
--
. the inside of a case stmt looks just like a stmt block .
. fallthru is a control function of 1 arg:
fallthru(case.stmt).stmt;
it expects its arg to be a case stmt .
1.5: inverting the default:
. a more intuitive use of the fallthru keyword
would be to have it used for
meaning just the opposite of the c lang's break stmt:
. when you wanted to fall-through,
then the fallthru stmt would be used to override
the default behavior .
1.5: minimize reserved words:
. instead of fallthru as a keyword
it might be better to reuse what we have,
such as (enter next),
-- "(next) doesn't have to be a reserved word,
because it's still local to the arg of function"enter --
or generalize it like this: [1.8:
enter case [some label within the case stmt] ].
adda/cstr/case/
the cases need not be literals:
1.2:
. whether the labels need to be const's,
being enums they eval to self,
so generally the case guard can always be eval'd;
you can also use expressions as literal cases
by quoting them, which supresses eval;
in that case,
the expr being cased should eval to etree;
because, a quoted expression is always an etree .
Labels:
adda,
case,
conditional,
cstr
2011-12-31
per-file dialect preference directive
12.28: adde/per-file dialect preference directive:
. when opening another author's strange dialect,
[@] adda/pre-processor/per-file dialect preference directive:
the editor auto-translates to your dialect .
. and when you name an object,
the editor asks how you came up with that name,
so that translators across country`languages
can have some clues for a good native alternative .
. when opening another author's strange dialect,
[@] adda/pre-processor/per-file dialect preference directive:
the editor auto-translates to your dialect .
. and when you name an object,
the editor asks how you came up with that name,
so that translators across country`languages
can have some clues for a good native alternative .
Labels:
adde
listable column view & tiled work trays
12.26: co.self/dream/adde/listable column view & tiled work trays:
. there are fixed layers for levels of the fs:
file, 3..5 folders levels for various intentions
[just like the biology has {species, genus, phylum, etc}]
. you see things arranged as columns,
[like mac`finder's column view,
but combined with the mac`finder [hierarchical] list view,
where more than one branch of the folder tree can be expanded]
then how do you arrange the rows to
keep files separate from folder systems ?
. have trays on the desktop,
corresponding to each of the columns;
they are easy for the user to rearrange, but they stay tiled;
and they have some way of stacking like mac has;
what way is that ? uh .
--[. I had done stim's just before bed;
because I was too stressed, and didn't want to be bored
in case there was insomnia;
I think I was half awake for this;
but it was dream-like in the sense of
the thought process being more concerned with
images of the ideas,
and not too quick to discount an idea as trivial or useless;
it does remind me that you can't really know
what users will find useless,
so the primary feature should be making it easy for
users themselves to design desktop behaviors .]
. there are fixed layers for levels of the fs:
file, 3..5 folders levels for various intentions
[just like the biology has {species, genus, phylum, etc}]
. you see things arranged as columns,
[like mac`finder's column view,
but combined with the mac`finder [hierarchical] list view,
where more than one branch of the folder tree can be expanded]
then how do you arrange the rows to
keep files separate from folder systems ?
. have trays on the desktop,
corresponding to each of the columns;
they are easy for the user to rearrange, but they stay tiled;
and they have some way of stacking like mac has;
what way is that ? uh .
--[. I had done stim's just before bed;
because I was too stressed, and didn't want to be bored
in case there was insomnia;
I think I was half awake for this;
but it was dream-like in the sense of
the thought process being more concerned with
images of the ideas,
and not too quick to discount an idea as trivial or useless;
it does remind me that you can't really know
what users will find useless,
so the primary feature should be making it easy for
users themselves to design desktop behaviors .]
Labels:
adde
encryption with shifting code
12.22: adde/encryption with shifting code:
. you have sections prefixed with the lang id
and the lang id is encrypted too .
how? if the lang code is not randomized or implicit
(eg, by a hash of the section's 1st words;
say, along with some other rule)
then opponents could work on common code sections
to see which words are most freequently used .
[and with implicit lang code, imagine that every word was encoded differently
so a word is in a file giving it an nth word location
and for each location's code there are 2 maps:
the word map: words -> code;
the map map: word location -> word map index .
. so for each word at location L,
my.word.map = [array of maps](map.map(L));
code = my.word.map (word) .]
. you have sections prefixed with the lang id
and the lang id is encrypted too .
how? if the lang code is not randomized or implicit
(eg, by a hash of the section's 1st words;
say, along with some other rule)
then opponents could work on common code sections
to see which words are most freequently used .
[and with implicit lang code, imagine that every word was encoded differently
so a word is in a file giving it an nth word location
and for each location's code there are 2 maps:
the word map: words -> code;
the map map: word location -> word map index .
. so for each word at location L,
my.word.map = [array of maps](map.map(L));
code = my.word.map (word) .]
Labels:
adde
taming the arrogant dialog
12.5: adde/gui/taming the arrogant dialog:
. one reason some dialogs will block any other actions
is to not lose your selection
or anything you've already input to the dialog .
. suppose the dialog were a separate window
and the selection in your document window changes,
then it needs to check selection;
and, if it changed, the user is asked
"(do you want to resume it?);
if the doc is modified, user is asked:
"(does new selection still fit your intention
for this old dialog?).
. sometimes the specific content of the original selection
will have determined the dialog type
(this is like a context menu selection by you,
only the app is doing it implicitely;
eg, if the selection contains both text and graphics,
then choosing style from the menu
should bring up dialogs for both text and graphics).
. if the document or the selection has changed,
then the dialog typing should be redone .
. if the dialog must be changed,
then the app must return the data by
logging* the parameter values provided by user
or also apply those changes to a
subsequent use of the dialog .
*: ( the entire user session is logged,
so that user's can know in writing what they did
that had the given effect; they can also use this writing
as part of developing scripts to automate their chores).
history stack traversal:
. it could just store modifications with the dialog,
and have a browser control with a back button
for earlier dialog fillings .
(warning:
. that works only in a protected acct with one user
otherwise that is a new behavior that could get very rude )
. this is a very important generalization:
html gui's can mean more service not less .
. one reason some dialogs will block any other actions
is to not lose your selection
or anything you've already input to the dialog .
. suppose the dialog were a separate window
and the selection in your document window changes,
then it needs to check selection;
and, if it changed, the user is asked
"(do you want to resume it?);
if the doc is modified, user is asked:
"(does new selection still fit your intention
for this old dialog?).
. sometimes the specific content of the original selection
will have determined the dialog type
(this is like a context menu selection by you,
only the app is doing it implicitely;
eg, if the selection contains both text and graphics,
then choosing style from the menu
should bring up dialogs for both text and graphics).
. if the document or the selection has changed,
then the dialog typing should be redone .
. if the dialog must be changed,
then the app must return the data by
logging* the parameter values provided by user
or also apply those changes to a
subsequent use of the dialog .
*: ( the entire user session is logged,
so that user's can know in writing what they did
that had the given effect; they can also use this writing
as part of developing scripts to automate their chores).
history stack traversal:
. it could just store modifications with the dialog,
and have a browser control with a back button
for earlier dialog fillings .
(warning:
. that works only in a protected acct with one user
otherwise that is a new behavior that could get very rude )
. this is a very important generalization:
html gui's can mean more service not less .
dual document view for speedy use of read-only
12.5: adde/gui/dual document view for speedy use of read-only:
. in order to be quick, the typical help system is read-only;
but friendly would be quick and annotatable .
. an editor can be made very lightweight
if it does only small chunks of simple text;
summary:
. this is possible by a windowing system that is
combining 2 documents:
the readonly panes load quickly despite being large;
the mutable panes load quickly because they are small .
. when you ok the pane, it saves that pane as a temp' file .
. deleting part of a readonly pane simply redraws the pane
without the part you deleted .
. after your annotation session,
it will merge results in the background .
idea#1:
. the annotation window is attached to the side
at a point that starts at finding current wrapped line
where the anchor phrase is found .
. finally, in the background,
the edits are merged with the doc .
idea#2:
. another view of a faster edit system
is that old text is never modified,
it is simply interleaved with panes of new text,
deletions have their before&after's
presented in the same read-only pane,
but the drawing is simply skipping the deleted range;
this may seem like a complication,
but no more so than having to
draw segments in separate panes .
. if the text is not word wrapped, (has frequent newlines)
then it should do a heuristic about whether
the after-piece should be on a new line
or the same line with the before-piece .
. for transitioning from rom text to mutable text,
there should be separate panes
to speed up the layout engine .
. within a read-only doc, after making selection,
you can do 3 things:
add your comment { above, below} it,
or replace it .
. in order to be quick, the typical help system is read-only;
but friendly would be quick and annotatable .
. an editor can be made very lightweight
if it does only small chunks of simple text;
summary:
. this is possible by a windowing system that is
combining 2 documents:
the readonly panes load quickly despite being large;
the mutable panes load quickly because they are small .
. when you ok the pane, it saves that pane as a temp' file .
. deleting part of a readonly pane simply redraws the pane
without the part you deleted .
. after your annotation session,
it will merge results in the background .
idea#1:
. the annotation window is attached to the side
at a point that starts at finding current wrapped line
where the anchor phrase is found .
. finally, in the background,
the edits are merged with the doc .
idea#2:
. another view of a faster edit system
is that old text is never modified,
it is simply interleaved with panes of new text,
deletions have their before&after's
presented in the same read-only pane,
but the drawing is simply skipping the deleted range;
this may seem like a complication,
but no more so than having to
draw segments in separate panes .
. if the text is not word wrapped, (has frequent newlines)
then it should do a heuristic about whether
the after-piece should be on a new line
or the same line with the before-piece .
. for transitioning from rom text to mutable text,
there should be separate panes
to speed up the layout engine .
. within a read-only doc, after making selection,
you can do 3 things:
add your comment { above, below} it,
or replace it .
1st-class subfile renaming
12.4: news.adde/fs/1st-class subfile renaming:
. Brandon Casey June 20th, 2007,
mentioned the idea of 1st-class subfile renamingwhich is a version tracking system that recognizes
when file modifications consist of subfile moves:
"( I split the file into two files in my repo.
File is modified in source repo.
I retrieve changes from source repo.
Will changes be correctly applied to
relevant sections in the two new files?
).
. Casey was responding to an article about
www.markshuttleworth.com/archives/123
tracking renames as a first class operation,
which I would call 1st-class file renaming;
so, Casey's idea is 1st-class subfile renaming .
. the minimalist style of version tracking
is to wait for a commit,
and then respond to modifications:
# directory changes are seen as
file {adds, deletes};
# file modifications are recorded with a
line-oriented diff' file .
. in previous notes on subfiles,
the system recognizes structure within files:
eg, html files have header tags, H1, H2, ... H6;
and, each represents a hierarchical subfile,
as do paragraphs, divisions, and other enclosing tags .
. the file system is just a tree of pointers;
likewise, this tree extends to subfiles;
and files become pointers to sections of text
which are actually in a database
named by their creation date & author
(plus an optional serial# for when
several subfiles have the same create date;
for example when a file is modified by
having some paragraphs inserted,
the paragraphs' create dates are considered to be
at the file's modified time .
).
. the branch copies db names
and each simultanious branch belings to one author;
so, that author'name must be part of a subfile's db name .
1st-class subfile renaming:
. the folder-subfile system is a tree:
a collection of nodes
(visualized as forks for representing enclosures )
and edges
(visualized as branches for representing
the things they contained by an enclosure ).
. a folder-representing node is thus remembering
# the name of the folder,
# edges to all nodes the folder contains;
likewise, a file-representing node has the file's name,
and the edges to subfiles it contains;
but, a paragraph-representing node
has a position number in place of a name
( so, when a paragraph gets inserted,
that bumps all the position numbers of paragraphs below
(within that subfile not the entire file)).
. when version-tracking for subfiles,
the nodes that were revised
are replaced with version-representing nodes
(version node) with edges to
both the replaced node,
and to the new node created by the revision;
in summary,
modified nodes are presented as a menu
of version choices;
eg, a folder-move creates version nodes twice:
once at both the source and destination nodes .
12.5:
. what if the version node is not the smartest
way to see changes?
the friendliest way is to show the various views:
# toc's for each version:
when there a high use of 2 views,
make sure both are fully built (not defined as a script)
the db will then be like a book with 2 toc's (table of contents).
# index:
. search of index finds every instance
showing you the pathnames,
and grouping together occurrences of
1 object is in several locations across versions .
# glossary:
. the place for histories of how a name has been used,
and why it has been changed from and to other names .
. this would include the human view of
why there systematic renames in certain versions .
. Brandon Casey June 20th, 2007,
mentioned the idea of 1st-class subfile renamingwhich is a version tracking system that recognizes
when file modifications consist of subfile moves:
"( I split the file into two files in my repo.
File is modified in source repo.
I retrieve changes from source repo.
Will changes be correctly applied to
relevant sections in the two new files?
).
. Casey was responding to an article about
www.markshuttleworth.com/archives/123
tracking renames as a first class operation,
which I would call 1st-class file renaming;
so, Casey's idea is 1st-class subfile renaming .
. the minimalist style of version tracking
is to wait for a commit,
and then respond to modifications:
# directory changes are seen as
file {adds, deletes};
# file modifications are recorded with a
line-oriented diff' file .
. in previous notes on subfiles,
the system recognizes structure within files:
eg, html files have header tags, H1, H2, ... H6;
and, each represents a hierarchical subfile,
as do paragraphs, divisions, and other enclosing tags .
. the file system is just a tree of pointers;
likewise, this tree extends to subfiles;
and files become pointers to sections of text
which are actually in a database
named by their creation date & author
(plus an optional serial# for when
several subfiles have the same create date;
for example when a file is modified by
having some paragraphs inserted,
the paragraphs' create dates are considered to be
at the file's modified time .
).
. the branch copies db names
and each simultanious branch belings to one author;
so, that author'name must be part of a subfile's db name .
1st-class subfile renaming:
. the folder-subfile system is a tree:
a collection of nodes
(visualized as forks for representing enclosures )
and edges
(visualized as branches for representing
the things they contained by an enclosure ).
. a folder-representing node is thus remembering
# the name of the folder,
# edges to all nodes the folder contains;
likewise, a file-representing node has the file's name,
and the edges to subfiles it contains;
but, a paragraph-representing node
has a position number in place of a name
( so, when a paragraph gets inserted,
that bumps all the position numbers of paragraphs below
(within that subfile not the entire file)).
. when version-tracking for subfiles,
the nodes that were revised
are replaced with version-representing nodes
(version node) with edges to
both the replaced node,
and to the new node created by the revision;
in summary,
modified nodes are presented as a menu
of version choices;
eg, a folder-move creates version nodes twice:
once at both the source and destination nodes .
12.5:
. what if the version node is not the smartest
way to see changes?
the friendliest way is to show the various views:
# toc's for each version:
when there a high use of 2 views,
make sure both are fully built (not defined as a script)
the db will then be like a book with 2 toc's (table of contents).
# index:
. search of index finds every instance
showing you the pathnames,
and grouping together occurrences of
1 object is in several locations across versions .
# glossary:
. the place for histories of how a name has been used,
and why it has been changed from and to other names .
. this would include the human view of
why there systematic renames in certain versions .
Labels:
adde,
vfs(virtual file system)
optimizing timemachine
12.4: adde/fs/optimizing timemachine:
. mac's timemachine can prevent corruptions;
adde's version of that could additionally preserve memory
(and thereby store more changes)
by analyzing how things change,
and asking the user why something got deleted .
--
. the inspiration for this idea was that
my data had be corrupted by a fat32 sd card error;
and although timemachine did save me,
all I really needed was
some automatic analyst to notice strange behavior:
the user fills up log entries,
but here one has been deleted ?
a folder had many files but is now null ?
12.5:
. the prior, simpler idea that helps as much
is to keep all user contributions in a read-only db,
and saving memory by automatic duplicate removal
(a file can saved as a script such as:
include these 3 subfiles,
and then replace phrase x with y ).
. adde questions the user upon each deletion:
why is this deleted?
# somewhere else: deleted when verified;
# not yours : did you want to log this? source?
# duplication:
adde has automatic duplicate removal .
. mac's timemachine can prevent corruptions;
adde's version of that could additionally preserve memory
(and thereby store more changes)
by analyzing how things change,
and asking the user why something got deleted .
--
. the inspiration for this idea was that
my data had be corrupted by a fat32 sd card error;
and although timemachine did save me,
all I really needed was
some automatic analyst to notice strange behavior:
the user fills up log entries,
but here one has been deleted ?
a folder had many files but is now null ?
12.5:
. the prior, simpler idea that helps as much
is to keep all user contributions in a read-only db,
and saving memory by automatic duplicate removal
(a file can saved as a script such as:
include these 3 subfiles,
and then replace phrase x with y ).
. adde questions the user upon each deletion:
why is this deleted?
# somewhere else: deleted when verified;
# not yours : did you want to log this? source?
# duplication:
adde has automatic duplicate removal .
Labels:
adde,
vfs(virtual file system)
Subscribe to:
Posts (Atom)
