Showing posts with label type. Show all posts
Showing posts with label type. Show all posts

2021-07-13

Dr.Barbara Liskov`the software crisis averted with modularity based on data abstraction

21.6.10:  7.12: news.adda/lang/

Dr.Barbara Liskov`the software crisis averted with modularity based on data abstraction:

. the key to programming in the large 

is modularity based on data abstraction

and that was not obvious before her work,

but now her work is mainstream, so it now seems obvious.

2015-01-02

#adda initialization

adda/initialization:
2015.1.2: image and string inputs:
. user-definable literal types reminded me of
user-programmable compilers
(what are the security implications of that?!)
but, the compiler doesn't need to be modifiable,
as the literals come as some composition of
just 5 literal types:
list, number, symbol enumeration, string, image .
. the type mgt's declaration of it's literal type
has nothing to do with the internal representation
of the type mgt's object's value;
so, for example, the string-initialized object
is not necessarily holding the string;
rather, just like the enum is converted to a number;
the type's mgt has its own parser
that converts the string into some data structure .
. the type's literal can be an image;
assuming the user's editor can display images,
the user can see the image or icon
instead of the image's hex representation .

2013-03-09

managing self-modifying code

1.31: adda/managing self-modifying code:
(inspired by python unpickle vulnerability)
. the safe pickle is built by the system .
. it can be compared to the decompile,
how is it extensible? that is to ask
how are objects built in the first place?

2012-11-17

class var's declaration syntax

adda/type/class var's declaration syntax:
8.21:
. how does the class var get declared?
how about just like it's called?
. if it's for the instance then we're
writing definitions for self implicitely,
but if there's a class var,
we write as if the var's name is "(type) ...
8.22:
. just as self's public vars are given as
just one tuple definition,
so too the public class vars are like so:
.< ... , type.(x.t), ... > -- a single public class var;
.< ..., .( x,y: t), ... > -- multiple public ivars;
. we could have also written that as:
.< ..., self.( x,y: t), ... >
. parentheses are required in a tuple syntax
even for the singleton? sure:
why have special cases confusing the reader?
in all cases of dotted naming, we are using a tuple,
which in all cases is represented by a parenthetical .
. how does this seem consistent
when generally x = (x) elsewhere?
it's consistent with other typedef syntax;
eg, in f().t the parentheses are required
in order to tell us that this is a function;
ie, any time we see f, we'll be expecting that
any next non-terminal found after f,
will be f's argument;
conversely, without the explicit paren's,
we'd expect f was not accepting args .

2012-11-16

Ada's core attributes

8.20: web.adda/ada/predefined attributes:
. what are Ada's reserved attributes?
here they are renamed for clarification
(these are just the most basic ones;
there are many more for floats, etc):
type'base  -- the unconstrained subtype;
enum in type'first .. type'last,
A'range(N) =  A'first(n) .. A'last(n) -- array's nth dimension;
type'value(enumcode number or image string);
type'image(value) is a string;
type'code(value) -- the integer representing the value (aka pos);
type'codebitsize -- obj's fixed size (when packed);
rec.component'codebitoffset;
type'imagesize -- #characters(for largest expression);
type'++(value) -- successor;
type'--(value) -- predecessor .

2012-11-15

task.type's syntax and semantics

adda/co:
8.16: syntax:
. when an object is given a message,
it is the object's type mgt that applies a method;
and, these type mgr's are tasks (co.programs);
but how do we get the obj's themselves
to be tasks? (ie, running code on a separate thread).

2012-11-09

substitution principle

8.21: adda/oop/type/substitution principle:
. when a parameter is type rectangle,
then it can be assigned any rectangle
including a square;
because, a square is rectangular .
. classic oop has had a problem with that,
so, how do we sort out our subtypes
from this jumble of subclass confusion?
[11.9:
. the solution I've come up with
is known as Changing The Language:
ie, rather than assume a type.tag is constant;
we assert that related types
are expected to have a common surtype;
eg, for a var constrained to Number.type,
it will have a constant surtype.tag;
but, it will also have a modifiable subtype.tag,
that can vary within {N,Z,Q,R,C}
(unsigned, int, quotient, real, complex).
. a var constraint can be a subtype too:
eg, for a var constrained to Real,
it can only vary in {N,Z,Q,R};
ie, the subtypes whose domains are
subsets of Real's domain .
. and, as usual for non-oop,
if a var is constrained to a definite type, such as float32,
then both the surtype and subtype
are going to be constant
(hence the obj will be untagged);
but, since the surtype is Number,
and float32 is understood to be a subtype of Real,
you can ask for (float32 + int)
and multi-dispatching will still work .]
. in order to be a subtype of rectangle,
an object that is tagged as being a square
has got to be re-taggable as non-square
in the event that the rectangle interface
asks it to modify itself;
ie, a type that inherits from rectangle
and then adds the constraint
that it be a square too -- forever --
has decided to nix support for type compatability,
which contradicts the idea of inheritance .
. to be a subtype (ie, support type compatability)
the inheritance needs to work like this:
my subtype named square
has the properties of the inherited rectangle
but includes the constraint width = height .
. if you ask me to break that constraint,
then I'll re-type.tag myself as a rectangle
(rectangular but not square).
[11.9: corrollary:
. if a var is constrained to be a square,
then the only rectangle it can be assigned to
is an unmodifiable one;
being assigned to a modifiable rectangle,
could potentially violate the type constraint,
and should result in a compile-time warning .
. this isn't a fatal error though;
because, the user could expect that
squares will grow in only a square way,
-- as would be the case for doublemy(rectangle) --
or the user may want to handle the exception
by trying another algorithm;
therefore, the warning should remind the users,
that they appear to be depending on
either having exceptions handle
the type.constraint.error,
or having the rectangle operation
not violate a square's subtype.constraint .]

2012-11-08

obj'c categories and Ada's hierarchical pkg

8.14: adda/oop/obj'c categories and ada hierarchical libs:
reviewing:
2012-01-31 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 type 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
the designers were assuming certain requirements
that are demanded only by the current oop model?

. if your string wants to express gui-specific tricks
such as appearing in a particular font,
or being arranged so as to follow a curve,
that need should be served by the use of a drawing record
which then has a string as one of it's parts .
(ie, it's ok to have 2 different classes !)
--
. a main point of the book"design patterns

was to critique oop's use of subclassing;
and, that criticism might apply equally well
to this use of categories;
but, generally, categories do have a good purpose:
they allow separate compilation of class extensions
without having to recompile the original interface
which might then require a recompile of
all the clients of that interface .

. this reminds of Ada's hierarchical libraries,
in Ada you can reuse oldlib's module
with the syntax:
package oldlib.additionalmethods
(by including oldlib's name like that
within your new package's name,
your new package includes the binaries of oldlib ).
. now current clients of oldlib
still don't have additional methods,
but, future clients of oldlib.additionalmethods
will have access to both modules
with that one import .
. obj'c categories by contrast,
allow you to add the same new modules
but this addition will also be affecting
current clients!
-- the category's method has access only to
the target's interface, not its internals;
so, a category can't fix every bug;
yet it can create bugs because it can
override system methods .

. I have 2 competing ideas on this:
# we should be able to describe in adda
any idea of any other language;
vs,
# we should not be supporting the use of ideas
that are either complicating or insecure .

here's how the the Category idea might be impl'd:
. when a datataype agrees to be modified by categories;
then at run-time, the type mgt is a modifiable object
and, it provides a dictionary
where you can see if it supports a message .
. it can dynamically add entries to this dictionary
(allowing it to support new messages),
and it can change method addresses
(allowing it to update the methods of old messages).
[10.8:
. now all we need is an uncomplicated way to
decide which types are so modifiable .
. perhaps a type wishing to participate
could declare one of its components to be
a dictionary with a standard name
(perhaps SEL, in honor of Obj'C);
then anytime a message is unrecognized,
the run-time would check SEL for the method .
11.8: correction:
. in order to work like an obj'c category,
it has to check SEL all the time,
not just when a message is unrecognized,
in case one of its methods got overridden .]

2012-08-23

mixing strings and numbers

7.17: adda/type/mixing strings and numbers:
. suppose the (+)-opererator can be used for
both addition and concatenation;
if we have to eval (string + number),
then the coercion should be to string,
since every number has a string image,
but not every string can eval to a number;
therefore, we should have it so that

2012-08-01

dialogs generated from type declarations

3.16: adda/type"gui/
dialogs generated from record.type decl's:

. the pyqt dialogs can be automated;
they are just like records
with a name of a field by a field value .
. the field`type determines the field value's widget type:
# short enum's can be a radio button;
# long enum types can be pull-down menu
or combo dial and value box .
--
. to validate a widget's input from the user,
we can run the adda compiler on it .

2012-07-02

automated range tracking

6.20: adda/type"float/automated range tracking:
. the float type should be replaced with the real range;
ie, as users of scientific calculators,
we're supposed to be doing this in our heads,
but a friendly calculator needs to automate this .
. for literals there could be an implied range
given by +|- 1 of the most significant missing digit,
eg, 1 = 0.9..1.1 because
it's missing 0.x so it's 1 +|- 0.1 .
. after literals the range cannot be implied;
we must keep track of how much operations are widening it .

2012-05-31

numeric literals

5.12: adda/syntax/value literals:
. since numeric literals from an arbitrary base
will be using the usual symbols,
we could declare them to be a numeric sub type:
11.B = 2*1+1,
11.B8= 8*1+1,
11.H = 16*1+1 .
. however, that doesn't work because then we are
reserving that symbol for the number literals;
what we need is a way to say BEEF.someType,
and still be able to say BEEF(base16)
in the same context .
. I had previously noted that
[@] 5.10: mis.adda/type/number's base like a dimension?
math's traditional way for expressing base
is with a subscript, hence BEEF#16;
my problem with that was that it
precluded many symbols from being array names;
but, now I see it could still be possible
if we use type names instead of the base's number:
H.type: number; BEEF#H .
but that does get noisy when combining with arrays!
eg, BEEF# BEEF#H = BEEF#48879 .

number sign for value of a type:
. how about a new context notation
for accessing a type's value:
Typemark#valueLiteral,
and then as a special case of that,
numeric bases are types:
eg, H#BEEF
-- not unlike Ada's  16#BEEF#;
but, we can't use 16#BEEF because
it's confusing when used as an array subscript:
eg, A# 16#10 ambiguously means either
A#(16,10) or A#(16#10) (returns an array) .

eg, B#10 for base 2, H#10 for hexadecimals,
O#10 for octals, and T#10 for tetroctals
(base 32 = 4*8 = tetra-oct-al = tetroctal).

review of multi-subscript arrays:
. AT.type: #.int; -- a named array type .
A#.AT; -- an array of array;
means the same as A#.#.int .
. then A is accessed as either A#i#j, or A#(i,j) .

currency sign for value literal spaces:
. another idea is that bases are not really subtypes,
so what we need is a new syntax for value literals:
. it could be like the above except replacing (#) with ($)
-- currency is the sign of value (as in worth);
eg, B$10 = 2, O$10 = 8, and H$10 = 16,
while $10 = still means usa cash;
but, $green can be an abbreviation for
color$green since green is obviously not a number .
. by having the option of using ($) on enumerations,
we can have separate name spaces for them,
so that I can use both the variable green
and the literal color $green in the same context .

TypeId#value vs ValueType$valueLiteral:
. types can be thought of as arrays of values,
so t#x evals x as one of t's values .
. B$10 = the value 10 as parsed by the binary value type .
Color#green works only if green is not redefined;
because in the expression (aType#x),
x can be any expression, not just a literal;
Color$green is always unambiguous;
because the ($) says what follows is
one of a type Color's literals .
.  RGB$(0,0,1) -- RGB color model for color literals .

5.10: mis.adda/type/number's base like a dimension?:

. can the notation indicating a number's base
be unified with the dimension system ?
not elegantly, because it confuses a concept:
. the number is a measure,
and the dimension indicates
which property is being measured;
whereas,
in the case of the numeric base indicator,
it indicates how to parse the text .

. we need special syntax for an identifier
to differentiate a typed symbol
from a typed literal value;
because,
the set of literals is indefinitely large from being
defined as a regular expression,
such that there are no identifiers left for symbols .

. numeric literals are from a reserved set of identifiers:
ie, no other symbols than numbers
can start with the digit characters;
but then in bases above 10,
the numeric literal can be confused with a symbol .
. notice too how bases share identifiers:
10 means something different in every base .
. therefore, each literal for non-default base
must have a syntax that says not only the base,
but the fact that this a numeric literal, not a symbol .

. the core system expects ( [, " ) to mean something special,
and all other symbols mean a symbol name .
. a string literal starts with (")
a numeric literal starts with a digit,
an operator symbol starts with non-alphanumeric;
and any other symbol starts with
([),(_), or an alphabetic .
-- literal expressions start with (')
but that's a 2nd meaning of literal because
other literals mean adda should neither parse nor eval,
whereas literal expressions should be parsed .

5.10:  adda/type/
defining value literals with regular expressions:

. the general way of handling expressions of literals
is to let the type mgt define it,
so numbers need not be part of the core lang at all,
instead being a module that comes with the core system .
. to generalize the way numeric type define literals,
a type mgt can defines its literals either as
enumerations or as regular expressions .
5.31:
. but if type mgt's are handling all reading of literals,
then constants types aren't known by their assigned values;
because, the value could be a literal,
and no longer implies a particular type .
. one way the above idea could still be useful,
is in talking about compilers that are partial,
and are completed by importing a set of native types,
so then these native types complete the definition of the compiler;
eg, the compiler generator's job is to
analyze all the given native types,
making sure that their literal definitions
are not overlapping .
. it would be a lot simpler to stay classical,
and make some native literals be part of the core language .

5.10:  adda/type/review of dimension systems:
. a number can have 3 parts
qty, dimension of qty, and thing being measured:
3 liter water
-- water is a noun measurable by either
volume, mass, moles, or monetary value .
5.12:
. dimensions are used by type physical;
the physical measure type includes  a pointer to
a symbol of type physical .

2012-04-30

multi-inheritance

4.14: adda/oop/multi-inheritance/
works with single-inheritance:
. how does the support for multi-inheritance
differ from that for single-inheritance?

[::] as a context clarifier

4.9: adda/syntax/type/[::] as a context clarifier:
. confusing having syntax"(type`value) when
(`) already has a specific meaning: (x`f);
so, maybe a good idea to use (::) as a
context specifier (type::value) ?
t.type: .< .(fields), .{values}, f(x).t, `method.t >
-- so then (x.t) lets me call { x`method, f(x) }
but if (`) was the context operator,
then we have { t::f, t::method }.

wrestling type syntax ambiguities

4.6: adda/syntax/
ensuring the 3 uses for colon are unambiguous:


. I had wondered if the labeling used in parameter naming
-- eg f(1,2) = f(p2: 2, p1: 1) --
could be confused with an array's description;
they are both mapping names to values,
but if you pass a named array to a function
are the names for the parameter's parts
or are they for the components of
an array passed to a single parameter?
. all functions are typed as having either one or more arg's,
so this will not be ambiguous,
though maybe not obvious to the casual reader .

. what about goto labels being confused with mappings?
all locals have to be typed explicitly,
and a goto label is a local,  so the type must be specified,
whereas parameter names and component names
will not include a type specification .

2012-03-31

python coroutines and generators

3.26: adda/type/streams/python coroutines and generators:
. after seeing python's coroutines and generators,
I was noticing that its function's signatures weren't explicit;
the syntax for generating coroutine should be:
f(x.stream.t1).stream.t2 .
. this tells you that when you pass f a file, x, of type t1,
it keeps reading units until you close x,
and it expects to be assigned to a stream,
which it continues to write to until f's input is closed .
y,x: stream; y`= f(x);
-- this causes f to function its stream .
. readers wait if x`item = eof
until there's a value to read .

packages compared to types

3.23: adda/type/packages compared to types:

. when were child packages needed by ada?
when you want to extend an existing package .
. the point is to reuse the parent package's object
without having to recompile .
. the child's object has links to the parent's object .
. parent package can be compared to supertypes;
they can use the same is.section syntax
to express the {super, parent} relation .

. adda records are not quite like ada packages,
so let us use the terms {record vars, record types};
record types allow you to include vars and subrograms
into an activation record;
each inclusion creates new instances of the vars .
. a record var at top level may be shared by
2 or more concurrently running subprograms .
. safely sharing a var requires the use of
a task's command queuing system .

. it seems possible to merge records and tasks;
ie, they don't need to differ in syntax;
every subprogram can be viewed as an entry;
and the default method for handling entry queues
is to select the queue with the longest line .
. if the compiler sees that vars aren't shared,
(ie, there is no sharing a top-level record instance,
then the optimizer can replace the queue with a direct call ).

pointerType ~ null

3.9: adda/syntax/type/pointerType ~ null:
. the syntax:
x.pointerType~null
means a pointer type that excludes null values .
. that could be slightly confusing
since this(~) is a truth or set operation,
it could apply to the object instead of its type;
but since (var~null) trivially reduced to var,
it will never be used,
so we can assume it applies to the type .

2012-01-31

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 ) .]

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 .