
http://www.newton-inc.com/dev/techinfo/qa/qa.htmmyEncloser := {
    importantSlot: 42,
    GetImportantSlot := func()
        return importantSlot,
    nestedSlot := {
        myInternalValue: 99,
        getTheValue := func()
            begin
            local foo;
            foo := :GetImportantSlot();            // WON'T WORK; can't find function
            foo := myEncloser:GetImportantSlot();    // MAY WORK
            importantSlot := 12;       // WON'T WORK; will create new slot in nestedSlot
            myEncloser.importantSlot := 12;        // MAY WORK
            end
    }
};
myEncloser.nestedSlot:GetTheValue();
_parent or _proto slot that references the enclosing frame.  Nesting the frame is not strictly necessary in this case, only the _proto or _parent references are used.MyFrame:= {}; theSlotName := "Slot_1";
MyFrame.Slot_1
Intern takes a string and returns a symbol. There is also a mechanism called path expressions (see the NewtonScript Reference), that allows you to specify an expression or variable to evaluate, in order to get the slot name. You can use these things to access the slots you want:    MyFrame := {x: 4};
    theXSlotString := "x" ;
    MyFrame.(Intern(theXSlotString)) := 6 
    theSlotName := "Slot_1";
    MyFrame.(Intern(theSlotName)) := 7;
    // myFrame is now {x: 6, Slot_1: 7}    call func() 
    begin
        local s,v;
        local root := GetRoot();
        local base := root.|YourApp:YourSIG|; // name of app
        local prot := base._proto;
        foreach s,v in base do
        begin
            if v and v <> root AND v <> base AND v <> prot then
              begin
               Write ("Slot:" && s & ", Value: ");
               Print(v);
              end;
        end;
    end with ()
TrueSize can also be a valuable tool to determine the heap used by your applications. See the NTK User Guide for more information about TrueSize.    thrower: func(x) begin
        if x then
            throw('|evt.ex.msg;my.exception|, "Some error occurred");
        end;
 
    returner: func(x) begin
        if x then
            return -1;    // some random error code,
        0; // nil, true, whatever.
        end;
 
    local s;
    for i := 1 to kIterations do
        try
            call thrower with (nil);
        onexception |evt.ex.msg;my.exception| do
            s := CurrentException().data.message;
    local result;
    local s;
    for i := 1 to kIterations do
        if (result := call returner with (nil)) < 0 then
            s := ErrorMessageTable[-result];
local s;
try
    for i := 1 to kIterations do
        call thrower with (nil);
    onexception |evt.ex.msg;my.exception| do
        s := CurrentException().data.message;
TRUE instead of NIL so the "error" occurs every time was interesting.  The return value loop takes about 60 ticks, mostly due to the time needed to look up the error message.  The exception loop takes a whopping 850 ticks, mostly because of the overhead in the CurrentException() call.breakOnThrows global to stop your code and look at why there's a problem.  With result codes you have a tougher time setting break points. With a good debugger it could be argued that you can set conditional break points on the "check the return value" code, but even when you do this you'll have lost the stack frame of the function that actually had the problem.  With exceptions and breakOnThrows, all the local context at the time the exception occurred is still available for you to look at, which is an immense aid.PrimClassOf will return an object's primitive type.String. A string object contains a 12-byte header plus the Unicode strings plus a null termination character. Note that Unicode characters are two-byte values. Here's an example:    "Hello World!"
kInkChar is used to mark the position of an ink word.  The ink data is stored after the null termination character.  Ink size varies depending on stroke complexity.    [12, $a, "Hello World!", "foo"]
    {Slot1: 42, Slot2: "hello"}
    {Slot1: 56, Slot2: "world"}
RelBounds to create the viewBounds frame, and it means there will be a single viewBounds frame map in the part produced.if value.path = '|name.first| then ...    // WRONG
'|name.first| is not a path expression, it is a symbol with an escaped period.  A proper path expression is either 'name.first or [pathExpr: 'name, 'first].  The vertical bars escape everything between them to be a single NewtonScript symbol.value.path = 'name.first will always fail, because path expressions are deep objects (essentially arrays) the equal comparison will compare references rather than contents.  You will have to write your own code to deeply compare path expressions.'name = [pathExpr: 'name] will always fail, as the objects are different.'name.first:if ClassOf(value.path) = 'pathExpr and Length(value.path) = 2
      and value.path[0] = 'name and value.path[1] = 'first then ...
    ...
    local myFunc := func(...) ...;
    local futureSoupEntries := Array(10, nil);
    for i := 0 to 9 do
        futureSoupEntries[i] := {
            someSlots: ...,
            aFunction: myFunc,
        };
    ...
TotalClone is made during the process of adding an entry to a soup, and this includes the function body, lexical scopes, and message context bound up within any functions in the frame.  All this  can take up a lot of space.DefConst('kMyFunc, func(...) ...))  it will not have the lexically enclosing scope, and the message context at compile time is defined to be an empty frame, and so cloning such a function will take less space.  You can use the constant kMyFunc within the initializer for the frame, and each frame will still reference the same function body.  (Additionally, the symbol kMyFunc will not be included in the package, since it is only needed at compile time.)_proto based scheme instead.  Each soup entry will necessarily contain a complete copy of the function, but if you can guarantee that the function body will always be available within your application's package, it might be unnecessarily redundant to store a copy with each soup entry.TrueSize to get the size of a soup entry I get results like 24K or even 40K for the size.  That can't  be right.  What's going on?TrueSize "knows" about the underlying implementation of soup entries.  A soup entry is really a special object (a fault block) that contains information about how to get an entry and can contain a cached entry frame.  In the information about how to get an entry, there is a reference to the soup, and various caches in a soup contain references to the cursors, the store, and other (large) NewtonScript objects.  TrueSize  is reporting the space taken up by all of these objects.  (Note: calling TrueSize on a soup entry will force the entry to be faulted in, even if it was not previously taking up space in the NewtonScript heap.)TrueSize is not very useful when trying to find out how much space the cached frame for an entry is using.  A good way to find the space used for a cached entry frame is to call gc(); stats(); record the result, then call EntryUndoChanges(entry); gc(); stats().  The difference between the two free space reports will be the space used by the cached frame for a given entry.    EntryUndoChanges(entry) will cause any cached frame to be removed and the entry to return to the unfaulted state.  Gc() then collects the space previouly used by the cached entry frame.TrueSize breakdown  of the types of objects used, you can Clone the entry and call TrueSize on the copy.  This works because the copy is not a fault block, and so it does not reference the soups/cursors/stores.Floor and Ceiling seem broken.  For instance, Floor(12.2900 * 10000) returns 122899, not 122900. What's going on? Floor or Ceiling. This happens because of the way floating point numbers are stored, and the limitation is common to many real number representations.  In the same way that 1/3 cannot accurately be represented in a finite number of digits in base 10 (it is .3333333333...), likewise 1/10 cannot be exactly represented as a fractional part in base 2.  Because number printers typically round to a small number of significant digits, you don't normally notice this.  The NTK inspector, for example, displays only 5 significant figures in floating point numbers.  However, if you display the number with enough precision, you'll see the representation error, where the real is actually slightly larger or smaller than the intended value.        FormattedNumberStr(0.1, "%.18f")  ->  "0.100000000000000010"    FormattedNumberStr(0.3, "%.18f")  ->  "0.299999999999999990"
Floor and Ceiling are strict, and do not attempt to take this error into account.  In the example, 12.29 is actually 12.2899999999999990, which multiplied by 10000 is 122,899.999999999990.  The largest integer less than this number (Floor) is correctly 122899.RIntToL, which rounds to the nearest integer avoiding the problems caused with round-off error and Floor or Ceiling.  RIntToL(x) produces the same result that Floor(Round(x)) would produce.    RIntToL(12.29*10000)  ->  122900
FormattedNumberStr.  These functions typically round to the nearest displayable value.  To display 2 decimal digits, use "%.2f":    FormattedNumberStr(12.29, "%.2f")  ->  "12.29"
$29.95 as the integer 2995 or 29950, then divide by 100 or 1000 to display the number.  If you do this, keep in mind that there is a maximum representable integer value, 0x1FFFFFFF or 536870911, which is sufficient to track over 5 million dollars as pennies, but can't go much over that.Floor deals with round off errors, you'll need to do some extra work keeping track of the precision of the number and the magnitude of the round off error.  It's worthwhile to read a good numeric methods reference.  Floating point numbers in NewtonScript are represented by IEEE 64-bit reals, which are accurate to around 15 decimal digits.  The function NextAfterD provides a handy way to see how 'close together' floating point numbers are.        FormattedNumberStr(NextAfterD(0.3, kInfinity), "%.18f");
                                                    ->  "0.300000000000000040"
        http://gemma.apple.com/dev/techsupport/insidemac/PPCNumerics/PPCNumerics-2.html
    1001.1100001 1.0011100001 * 2^3 3+0x3FF = 0x402 = 100 0000 0010 0 10000000010 0011100001000000000000000000000000000000000000000000 0x4023840000000000StrHexDump(9+97/128, 16) -> "4023840000000000"real.  In addition to the NewtonScript floating point literal syntax, you can use the compile time function MakeBinaryFromHex to construct real numbers, and you must use this style for custom NaN values.  The most recent platform files for Newton 2.0 and Newton 2.1 provide constants for negative zero (kNegativeZero), positive and negative infinity (kInfinity, kNegativeInfinity), and a canonical NaN (kNaN). MakeBinaryFromHex("4023840000000000", 'real) -> 9.7578125 // = 9+97/128