2012-11-17

concurrency both expressed and automated

8.23: adda/co/finding inherent concurrency automatically:
. how can we analyze a program in order to find
what parts of it can be done concurrently?
. at each step there are implicit inputs and outputs
for step#1, do I know its outputs?
for step#2 do I know its inputs?
(also, when step#1 makes calls,
do any of those calls modify any space that might be
needed by anything step#2 calls? ).
. if step#2's inputs don't intersect step#1's outputs,
then you can do both at the same time .
. to know these things, calls have to be
functional so that program space is obvious .

. when calls have multiple parameters,
the order of their evaluation is random;
which should be tantamount to saying
that parameters in the same tuple
can be run concurrently (co-runnable) .
. this also applies to all tuples that are at
the same level of an expression tree:
eg, in h( f(a,b), g(c,d) ), a,b,c,d are co.runnable .

. a low-level way to compare
subprogramming with coprogramming,
is that while any call could be seen as
a new {process, cpu} activation,
in subprogramming, after making a call,
it agrees to stop working until that call is done .

. often we can find that a group of operations
are all handled by the same type mgt, [11.17:
-- in fact, that is the definition of "(operation):
a subprogram that is outputting
the same type that it's inputting -- ]
so even though they are nested
you can send the whle thing in one call,
and, in that case,
the type mgt will know what's co.runnable .

8.23: todo.adda/co/review parasail's design:
. the parasail lang was able to parallelize implicitly a lot .
(see also comments of this page).

adda/co/explicit concurrency control:

. the abstraction to use for explicit concurrency control
is having a particular cpu called like a function:
cpu#n(subprogram, inputs, outputs)
-- the inputs are a copy of everthing sent to it .
-- outputs are addresses to put results in .

. how is go.lang outputting?
when go.lang says go f(x)
they expect f to either call an outputter
or have x be an outputting channel .

. instead of saying cpu#n(...)
just say co f(x, out), or y`= co f(x) .

8.24: adda/co/syntax:
. there are 2 forms of the function co
according to whether co is synchronous or asynch:
# co(f,g,h) -- co with multiple arguments --
expects spawn and wait .
# co f -- co with just one argument --
just launches f asynchronously .

8.31: co.self/dream/adda/co:
. the dream was something about
"(ways of doing backup for concurrency or ...)
"( ... and now that we can do that,
we can do this ...) [dream recall is too fuzzy].


rationales for go.lang's surprises

8.22: news.adda/go/assertions are no way to panic:
Why does Go not have assertions?
[ assertions allow you to say
crash if this condition doesn't hold true
because something is wrong
and the program will need debugging .]
. assertions are undeniably convenient
to avoid thinking about proper
error handling and reporting;
but, servers should not crash from non-fatal errors;
and, errors should be direct and to the point,
saving the programmer from interpreting a
large crash trace .
Precise errors are particularly important
when the programmer seeing the errors
is not familiar with the code.
no exceptions? well, panic is just as useful:
. func panic(interface{})
func recover() interface{} .
. these built-in functions assist in reporting and handling
run-time panics and program-defined error conditions.
. When a function F calls panic,
normal execution of F stops immediately.
Any functions whose execution was
deferred by the invocation of F
are run in the usual way,
and then F returns to its caller.
To the caller,
F then behaves like a call to panic,
terminating its own execution
and running deferred functions.
This continues until all functions in the goroutine
have ceased execution, in reverse order.
At that point, the program is terminated
and the error condition is reported,
including the value of the argument to panic.
This termination sequence is called panicking.
panic(42); panic("unreachable");
panic(Error("cannot parse")).
. The recover function allows a program to
manage behavior of a panicking goroutine.
Executing a recover call inside a deferred function
stops the panicking sequence by
restoring normal execution,
and retrieves the error value passed to the call of panic.
If recover is called outside the deferred function
it will not stop a panicking sequence.
In this case, or when the goroutine is not panicking,
recover returns nil.

go vs python from the trenches 2012

8.22: news.adda/go vs python from the trenches 2012:
Graham King:
Would I be happy working with Go as my
main language? Yes, I would.
It’s a joy to work with,
and I got productive very fast.
Am I using it instead of Python
for all my new projects?
No, There are two reasons for that.
Firstly, it’s a very young language,
so library availability is limited
(for example, I need curses).
Second, well, Python is just so amazing.
[but] I see the benefit of static typing.

If I was still doing Java, or (heaven forbid) C++,
I would invest heavily in Go.
It was designed to replace them, and it does that well.
Go’s sweet spot is building servers.
(it makes concurrency safer and easier)

Other claimed benefits of Go over Python
are that it’s faster, and it’s “better at scale”.
For some things I’ve done
Python has been faster .
[and] The biggest difference [in speed]
is probably [just] in how well I write the code.
[also] nothing I do is CPU bound.
The “better at scale” argument doesn’t really apply
to building web apps with Django.
We scale by adding servers,
and [Django supports programming-in-the-large
with small self-contained ‘apps’ ]
Steven (March 6, 2012 at 23:22)
You can get pretty close to a REPL
[an interactive Read-Eval-Print Loop]
with goplay, [a web-based go compiler]
-- instead of interpreting, it compiles
[ go was designed for very fast compiling .]
Go is possible to daemonize.
You could use a sync.WaitGroup
to make main wait for any number of goroutines to exit .
But more directly, you can do the same thing by
adding this to the top of your program:
defer runtime.Goexit()
write CPython extensions with Go:
. goPy with gccgo .
Once the libraries and command-line tool are installed,
the "gopy" command-line tool
is generating the necessary C interface code;
and, then using gccgo will compile the code
into an extension module.

walk and chew gum #Python

8.22: news.adda/python/co/walk and chew gum:
summary:
Google discourages Python for new projects?
[they encourage go.lang;
Python is said to need more resources?
I'm sure the problem is backwards compatibility .
. in the paper where they talked about Unladen Swallow
they mentioned wanting to remove the GIL
(the global interpreter lock for thread safety)
and this really surprised me coming from google staff,
because Python's project lead (another google staff)
has argued convincingly
that due to the language itself, [11.17:
ie, by being designed for interfacing C
(Jython and IronPython have no GIL)]
removing the GIL from CPython was impractical .
[11.17: at PyCon 2012, he adds:
Threading is for parallel IO.
Multiprocessing is for parallel computation.
The GIL does not hinder any of that.
... just because process creation in Windows
used to be slow as a dog, ...]
. Python has that old-style OOP,
which doesn't do much for encapsulation,
and therefore doesn't do much for thread safety
except to single-thread the interpreter .
. if you want something much like python
that also has good concurrency,
then google has given it to us in go.lang;
but, perhaps what he meant to say
is that it's like Intel's CISC architecture:
that was fundamentally slower than RISC;
but they virtualized it:
the machine instructions are converted
to RISC microcode .
. that's what big money could do for Python:
automatically find the inherent concurrency
and translate it to a threaded virtual machine .[11.17:
... but still interface flawlessly with
all C code on all platforms?
I'm no longer confident about that .]

[11.17: web:
. to overcome GIL limitation,
the parallel python SMP module;
runs python code in parallel
on both multicores and multiprocessors .
Doug Hellmann 2007 reviews it:
. you need install your code only once:
the code and data are both auto'distributed
from the central server to the worker nodes .
Jobs are started asynchronously,
and run in parallel on an available node.
The callable object that is
returned when the job is submitted
blocks until the response is ready,
so response sets can be computed
asynchronously, then merged synchronously.
Load distribution is transparent,
making it excellent for clustered environments.
Whereas Parallel Python is designed around
a “push” style distribution model,
the Processing package is set up to
create producer/consumer-style systems
where worker processes pull jobs from a queue .
Since the Processing package is almost a
drop-in replacement for the
standard library’s threading module,
many of your existing multi-threaded applications
can be converted to use processes
simply by changing a few import statements .
. see wiki.python.org/moin/Concurrency/
for the latest on Pythonic concurrency .]

8.22: news:

allowed characters in identifiers

8.22: adda/lexicon/allowed characters in identifiers:
. if the allowed characters in an identifier
could include the dot,
then there could be confusion in places,
as to whether the dot was declaring a var:
eg, what if you have the name x.F.int,
and then -- forgetting you did that --
decided later to define F.type ?
. now x.F is ambiguous:
are you declaring x to be F.type?
or are you referring to x.F.int ?
. therefore, the allowed identifiers are
first character is a letter
or the character (_);
and, subsequent characters are alphanums
or the characters (') (_) (-);
anthing else gets put in a box:
eg, [x.F].int; .

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 .

arrays are records are tuples

8.19: adda/dstr/array and record syntax as modes of access:
if ( x.y ) and ( x#y ) are both valid
regardless of whether x is defined as an array or record;
this ignores an idiom where
arrays represent lists of items,
while records represent items with named parts;
. well, my way lets you do it both ways,
but it should be admitted that the writer's freedom
is inevitably the reader's headache .

adda/dstr/array vs record precedence:
. if you have x#y.z
does it mean x#(y.z) or x#(y).z ?
my first impression is that y.z is the tightest binding;
ie, it means x#(y.z);
also, (x#(y) = x#y) only when y is an atom,
and you could argue that y.z is not an atom:
it's a sort of address-addition operation; [11.16:
but, of course, that would be a stretch!
it's more intuitively seen as a style of atom naming .
. finally, consider how functions and arrays
should be similar;
( f x.y ) should be seen as a variant of
( a# x.y ); therefore, the parsing is ( a#(x.y) ). ]
. x.y#z is unambiguous: x has component y,
which is an array taking parameter z;
ie, it's parsed as ( (x.y)#z ).

8.20: adda/dstr/arrays are a species of record.type:
. an array is generating a list of component names,
and then declaring them all to be the same type .
. records are a generalization of this,
where a generated list of components
can have a variety of types .
. in fact, fully-oop arrays are actually records;
because, they often have a variety of types .
. arrays are parameterized types,
and records can be parameterized too
. here's a syntax for allowing a record
to describe parts of itself the way arrays do:
reca(n.int).type: ( a.t1, b.t2, #(0..n).t3 );
x.reca(3)
-- now x = (a:..., b:..., 0:..., 1:..., 2:..., 3:... ).

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 .

model-view and composite tech

[thought I blogged this 9.2, but found as draft;
then found a note that the reason it was draft
was a concern that the body was still too buggy;
nevertheless, the first part is still interesting .]

7.17: web.adda/architecture/MVC vs MVVM:
8.31: summary:
. in trying to find an explanation of
the essential differences between
all the variants of the MVC architecture,
it was most helpful to see Alexy Shelest's
2009`MVC vs MVP and MVVM:
first he reminds us of MVC's original definition:
"( the “Gang of Four” book
doesn't refer to MVC as a design pattern
but as a “set of classes to build a user interface”
that uses design patterns such as
Observer, Strategy, and Composite.
It also uses Factory Method and Decorator,
but the main MVC relationship is defined by
the Observer and Strategy patterns. ).
[8.31:
. then, Shelest had an interesting summary of
the historical evolution of MV-architectures, eg:
"( Potel questioned the need for the MVC's Controller;
He noticed that modern user interfaces
already provide most of the Controller functionality
within the View class,
and therefore the Controller seems a bit redundant.).
. after reading that, I wrote this:
. I didn't get mvc either, and promptly redefined it:
subrograms should not be controlling a gui interface,
rather they should be designed primarily for
use by other subprograms,
just as unix tools are meant to be .
(well, unix takes a shortcuts by
making its tool language a character string
that could also be readable by humans
but that was a security blunder because of parsing errors
that confuse critical datatypes like
{filenames, command names}).
. so, anyway, back to how humans fit in:
in order for a human to interact with
a subprogram that speaks type-tagged binary,
the human needs an agent who will
convert this robot speak into a gui .
. this agent is the Controller of the Model subprogram,
and it creates a View the human can interact with .]

benefits of unique context operator

8.19: adda/lexicon/benefits of unique context operator:
[8.20: intro
. in 2012.4, this "(::) was presented as a context operator
but it didn't give a specific reason:
"( confusing having syntax"(type`value)
when (`) already has a specific meaning: (x`f); ). ]
. even more than confusing,
it's name`space limiting:
if you have the syntax ( type`attribute ),
along with ( type`method ),
then the type authors are limited in
what they can name their methods
because it could clash with type attributes; [8.20:
eg, for enums there is an attribute named first;
eg, for bible.type: {last, first},
bible`first = last; -- this type's first value is "(last);
but if the context operation uses the same symbol,
then ( bible`first ) could mean either
the first value of the bible enumeration,
or the bible value named "(first).
. by having a separate context operator (eg, ::),
we can say ( bible`first = bible::last ).]

8.19: 11.15 .. 16: review the syntax:

obj.type(select a variant of this type)
-- declares obj to be of this type;
obj`= value -- object initialization;
type::value -- fully-qualified enumeration value;

obj.component -- public ivar;
type::.component -- public ivar's default initial value;
obj#(component expression) -- public ivar;
type::#(expr) -- public ivar's default initial value;

type.component -- public class var;
type#(component expression) -- public class var;

obj`body/local -- private ivars;
type`body/local -- private class vars;

obj`message(...);  -- instance message call;
obj`message`body -- instance message's body;
type::`message`body -- instance message's body;
type::`message -- instance message uninstantiated
( practically the same as type::`message`body );
type`attribute -- class message call;
function(obj) -- call to function of instance
(may or may not belong to an obj's type's interface);
type::subprogram -- full-qualified subprogram call;

type::function`body -- access function's body;
type`body/subprogram -- private class subprogram call;
obj`body/subprogram -- private instance subprogram call;
obj(expr) -- obj callable? apply('obj, expr);
function obj -- call with this obj

. notice there are separate namespaces for
{ value and function names
, .components
, `messages }; because,
components are found only after a dot,
and messages only after a backquote;
whereas, the namespace for value
is shared by that for functions;
otherwise, the parser would have problems:
both values and functions start with a name
but only functions expect the next lexel
to be the argument of that function:
# function x -> apply function to x;
# value x -> syntax error
( unless x is a binary operator
or value is numeric and x is a dimension ).
. therefore, for each unqualified name
it must be typed unambiguously as
either a function or a value, not both .

11.15: mis:
"(review the syntax:
type::value -- fully-qualified instance value
type::`message -- access message's body
type::function(...) -- access function's body
obj`body/local -- private ivars;
type`body/local -- private class vars;
type`attribute -- class message call;
...
) . sometimes it is using (type::x) to mean eval x,
but other times don't eval?
and then this:
type`body/local -- private class vars;
?
. the body of the function is within
the body of the type:
type`body/function
and the way to refer to the function uneval'd,
is to ask for the function's body:
type`body/function`body .
. but if the function is also visible from the interface
we could also write:
type::function`body .

11.16: clarification:
"( review the syntax:
type.component -- public class var;
obj.component -- public ivar;
type::.component -- public ivar's default initial value
) . an interface definition has syntax for
both class and instance public vars,
and these are accessed similarly,
being dotted with their respective objects:
obj.component -- public instance var;
type.component -- public class var .
. if you hadn't defined an instance yet,
and still wanted to refer to an instance's component,
that would be done with the type's context operator:
type::.component;
and, since there was no instance involved,
the only meaning it could logically have
is being the component's default initial value .

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-11

read-only and write-only params

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

API-GUI equivalence

8.7: adda/api-gui equivalence:
intro:
. every aspect of a subprogram's gui
should be mapping to some feature of
the subprogram's interface (API);
so how is the API specifying
an array of menus with submenus?
sometimes there is menu-izing naturally formed by
an app inheriting from a service type,
like the file menu is,
for apps that use the file system .
. a datatype's operations are going under the Edit.menu;
because, that's the general term for the current datatype .
. a View.menu would belong to the human's agent
that was providing various ways to
format the display of data; [11.11:
but, a subprogram's API might have multiple views too .]

2012-11-10

signaling in gui systems

8.12: adda/cstr/signals/signaling in gui systems:
how is the gui related to the signal?
. as a summary of 2012/07/gui-notification-systems
I was thinking gui's should be impl'd with
gui-optimized signals,
rather than the general signal system,
but then I wondered if that idea was
keeping mvc in mind,
so that generally all IPC (interprocess communications)
would be seeing the same windows that a
human can see with the help of a gui agent .

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-11-02

PLY(Python-based Lex-Yacc) and pyCparser

8.20: web.adda/dev.py/ply
11.2: PLY compared with ANTLR:
There are several reasons to use ANTLR
over one of the Python parsers
like PLY and PyParsing.
The GUI interface is very nice,
it has a sophisticated understanding of
how to define a grammar,
it's top-down approach means the
generated code is easier to understand,
tree-grammers simplify some otherwise
tedious parts of writing parsers,
and it supports multiple output languages:
its builds parsers best in C, C# and Java;
but also has some support for generating Python .
ANTLR is written in Java;
Unlike the standard yacc/lex combination,
it combines both lexing and parsing rules
into the same specification document,
and adds tree transformation rules
for manipulating the AST.
. so, if you prefer python tools over Java, PLY ahead!