newton technology journal: volume 1, number 4

Upload: pablomarx

Post on 03-Apr-2018

217 views

Category:

Documents


0 download

TRANSCRIPT

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    1/24

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    2/24

    August 1995 Newton Technology Journal

    2

    NTK 1.5 SIGNALSNEWOPENINGSONNEWTONPLATFORM

    Last month brought scoresof developers

    to Apple Computersannual Worldwide

    DevelopersConference to hear the latest

    newsand check out the newest

    technologiesfrom Apple. Amidst the

    sessionson Macintosh, the Newton

    SystemsGroup packed itsmeeting rooms

    with developerseager to learn about

    Newton Platform directionsand

    technologies. In a standing-room only

    setting, we delivered the latest newson

    the Newton Toolkit 1.5. The content of this

    session and the otherson the Newton

    platform set the tone for Applesfuture

    directionswith respect to platform tools

    and Newton application development. In

    case you missed that session, let me

    highlight the keypointsand provide some

    more insight on where were headed and

    how you fit in.

    The newest version of the Newton

    Toolkit (NTK) isthe product that you asked

    for and isindicative of the changesgoing

    on inside of the Newton SystemsGroup and

    the platform at large. NTK 1.5ismore open

    and flexible, asisthe future of the platform.

    Weve provided the compiler you asked for

    and delivered a profiler that allowsyou to

    test your code to determine whether

    compiling makesa difference in your codes

    speed and size. Unlike other compilersyou

    maybe used to, you should not always

    compile your code. In fact, you mayeven

    make your code larger and slower by

    compiling. Use of the profiler will let youdetermine which routinesin your Newton

    application will benefit from being compiled.

    The choice of exactlywhat code to compile

    isup to you. Bob Ebertsarticle on NTK 1.5

    in thisissue of NTJwill highlight some key

    pointsin using the product and some areas

    where you should be cautious. Thisis

    critical reading for those looking forward to

    working with thisnewversion of NTK.

    While we think you will laud the opening

    of the toolsasanother step in the right

    direction for you, it isclear that with the

    increased flexibilityand choice comes

    increased risk and responsibili ty. When the

    Newton platform wasintroduced, the tools

    were closed and the developer was

    protected from mistakes. While that

    protection yielded easyapplication

    development, it reduced power, control,

    and creativityon the part of the developer.

    We look forward to seeing the resultsthat

    the newchoicesand flexibilityin NTK 1.5

    allowfrom the applicationsyou develop.

    So the movement awayfrom closed and

    protected to open and flexible meansmore

    choices, more power, and more

    responsibilityfor Newton developers. It

    also meansgreater possibilities. Thisis

    clearlythe theme moving through all of the

    future directionsfor the platform and you

    will continue to experience more of this.

    Future toolswill include Windowsversions

    of the Toolkit, and C+ + toolswhich will

    allow for even broader access. Well be

    providing broader accessto driversfor

    communicationsand PCMCIA development.

    Finally, we see the development of third-

    partytoolsplaying a growing role in

    opening up the platform. All kindsof

    changesare afoot in the Newton Systems

    Group platform strategythat will benefit

    our businesspartnersand developers.

    What exactlydo all of these changes

    signifyto the Newton developer

    community? Isit a lossof arrogance fromthe Newton SystemsGroup? Isit simplya

    change in philosophy? Probablya little bit

    of both. But more importantly, itsa big

    change in the businessmodel to that of a

    customer focused, customer driven model.

    We think youll benefit from these changes

    and your applicationswill show it. The

    newfeaturesin NTK 1.5 are just the first

    Published by Apple Computer,Inc.

    Lee DePalma Dorsey Managing Editor

    G erryKane Coordinating Editor,Technical Content

    D avid G lickman Coordinating Editor, Business

    Content

    G abriel Acosta-Lopez Coordinating Editor, DTS and

    Training Content

    Philip Ivanier Manager,Newton Developer Relations

    Technical Peer Review Board

    J. Christopher Bell,Bob Ebert, Jim Schram,

    M aurice Sharp, Bruce Thompson

    Contributors

    Bob Ebert, M aurice Sharp, Julie M cKeeham,N eil

    Rhodes, Ed Colby, Russel D. M atichuk,

    Produced by Xplain Corporation

    N eil T icktin Publisher

    John Kawakami Editorial Assistant

    Judith Chaplin Art Director

    1995 Apple Computer,Inc.,1 Infinite Loop,Cupertino,C A95014, 408-996-1010. All rightsreserved.

    Apple, the Apple logo, APD A, AppleD esign, AppleLink,AppleShare, Apple SuperDrive, AppleTalk, HyperCard,LaserWriter,Light Bulb Logo,Mac,M acApp,Macintosh,M acintoshQ uadra, MPW, N ewton, N ewton Toolkit, N ewtonScript,Performa, Q uickT ime, StyleW riter and WorldScript aretrademarks of Apple C omputer, Inc., registered in the U.S. and

    other countries. AO CE, AppleScript, AppleSearch, ColorSync,develop, eWorld, Finder, O penD oc, Power M acintosh,Q uickD raw, SNA ps, StarCore, and Sound M anager aretrademarks,and AC O T isa service mark of Apple Computer, Inc.Motorola and M arco are registered trademarksof M otorola, Inc.N uBus is a trademark of Texas Instruments. PowerPC is atrademark of International BusinessM achinesC orporation, usedunder license therefrom. Windowsis a trademark of M icrosoftCorporation and SoftWindowsisa trademark used under licenseby Insignia from Microsoft Corporation. UN IX is a registeredtrademark of UN IX System Laboratories, Inc. CompuServe,Pocket Q uicken byIntuit,CIS Retriever byBlackLabs,PowerFormsbySestra, Inc.,ACT! bySymantec,Berlitz,and all other trademarksare the propertyof their respective owners.

    Mention of products in this publication is for informationalpurposes only and constitutes neither an endorsement nor arecommendation.All product specificationsand descriptionswere

    supplied by the respective vendor or supplier.Apple assumesnoresponsibility with regard to the selection, performance, or use ofthe products listed in this publication. A ll understandings,agreements,or warrantiestake place directlybetween the vendorsand prospective users. Limitation of liability: Apple makes nowarrantieswith respect to the contentsof productslisted in thispublication or of the completenessor accuracyof this publication.Apple specifically disclaims all warranties, express or implied,including, but not limited to, the implied warranties ofmerchantabilityand fitnessfor a particular purpose.

    g g Newton TechnoloJ O U R N A L

    Volume I, Number 4 August 1995

    by Lee DePalma Dorsey, Managing Editor

    Editors Note

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    3/24

    Newton Technology Journal August 1995

    3

    Page references throughout the excerpt refer to sections of Wireless for

    the Newton .

    Anytime, anywhere communications isone of the mottoesof theNewton. Indeed, communicationsisone of the hottest areasof

    development within the computer industry, in general, and on the

    Newton, in particular.

    The Motorola Newton, the Marco, providesNewton userswith an

    important feature previouslyunavailable in a Newton: built-in two-way

    wirelessradio. Thisnew feature givesthe Newton user wirelessaccess

    to a nationwide electronic network that includesa gatewayto the

    Internet. Thisallowsa wide range of new capabilities, including the

    abilityto send and receive wirelessmail to and from the Internet.

    Marco Specialized Transports for SupportingWireless Mail

    The Marco Newton comeswith a dual protocol (MDC4800 at 4.8

    Kbps, RDLAP at 19.2 Kbps) radio modem that connectsto the ARDIS

    network. A user can have an ARDIS Personal Messaging (ARDIS PM)

    service agreement with ARDIS which enablessending messagesto and

    from other ARDIS PM usersor to hostson the ARDIS network. A user can

    also establish a service agreement with Radiomail, which providesa mail

    gatewayto the Internet.

    To enable thisfeat of wirelessmagic, Motorola hasprovided two

    specialized transportswhich handle the interaction between the two

    services:

    ARDISPersonal Messaging Thistransport providesthe abilityto send

    and receive messagesfrom other ARDIS PM

    users.

    Radiomail Thistransport providesthe abilityto send

    and receive messagesfrom the Internet.

    Programmingthe Marco

    Anyapplication that hasprovided mail support (see Mailing on page

    44) will automaticallysupport wirelessemail. Once the user haschosenhowto send mail (for example, ARDIS PM to another ARDIS PM user,

    Radiomail to send via the Internet, NewtonMail using a wired modem, or

    some custom transport) , it will be automaticallysent from anyapplication

    via the specified transport.

    NewMotorola APIs

    Motorola hasalso offered the programmer other waysof making a

    Newton application interact specificallywith the Marco. There are three

    APIsthat a Newton application can use, depending on the type of

    application it is:

    Mail-based Applicationsthat send mail directly

    (without using the action menu) and

    receive mail directly(without requiring the

    user to use the In Box). These applications

    should use the Universal Mail Services(UMS)

    API.

    Transport-specific Applicationsthat require a specific

    transport and communicate with that

    transportsAPI . Built-in transportson Marco

    are Radiomail and ARDIS PM. Other transportscould be

    provided in the future.

    Dedicated host These applicationswrite directlyto the

    WirelessManager endpoint. Theysend

    packetsto a specific host on the ARDIS

    network.

    Use of anyof these APISsmakesyour application Marco-specific.

    Of these three typesof transports, we will be dealing with the first,

    mail-based applications. We will cover it in detail since the vast majority

    of Marco-specific applicationswill be of thistype.

    Note:

    It is possible, using the Wireless Manager endpoint, to write your own

    transport (a service which is io box-based, and which is available to all

    appli cations). For example, you could provide a transport that accesses your

    enterprise-wide email system. By simply connecting to a host on the ARDIS

    network and writing transport software that would connect to the email

    system. Incoming mail would appear in the In Box. Users could use the

    action button to mail to a user on the enterprise email system. The mail

    would go to the Out Box, and then out via the ARDIS network to the host on

    that network.

    For information on the transport-specific APIs, on the Wireless

    Manager API , or on writing your own transport, you should contact

    Motorola at MotoNewt.Dev@ applelink.apple.com.

    Writingto the Mail-based API

    There are two partsto mail-based applications: sending mail without

    going through the action button and mail slip, and receiving mail

    without requiring the user to go through the In Box. Sending mail

    without going through the action button hasalreadybeen covered

    (see Posting to the Out Box Programmatically on page 57). The

    second part, receiving mail automatically, isdone byregistering your

    application.

    Programming Wide-Area CommunicationsUsing the MarcoExcerpted from Wireless for the Newton by Jul ie McKeehan and Neil Rhodes. AP Professional.

    Communications Technology

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    4/24

    August 1995 Newton Technology Journal

    4

    Registeringan Application and SendingMail

    To register an application to receive mail, you use the

    RegisterMailPackagemethod (a method of the

    motorola global frame). Thismethod takesone parameter, your

    application symbol.

    When a piece of mail arrives, the mail system goesthrough the

    registered applications, sending each a message along with the piece

    of incoming mail. Each application checksto see whether the incomingmail belongsto it. If it does, it handlesit and returnsnil. Otherwise, it

    returnsthe mail, which ispassed to the next registered application.

    If no registered application handlesthe mail, it isplaced in the In

    Box (asalways). figure 2.2 showsa graphic representation of this

    process.

    Figure 2.2 How the Marco handles incoming mail.

    ReceivingIncomingMail

    The message sent when incoming mail arrivesis

    receivedMailScript. The parameter thismethod takesisa frame

    containing at least the following slots:

    dateStr The date of the mail asa string.

    fromEmailAddress The email addressof the sender.

    fromName The user-readable name of the sender.

    toEmailAddress The email addressthe item wassent to.

    n a m e The user-readable name at the mail

    address the item wassent to.

    title The title of the mail message.

    text The bodyof the mail message.

    Unregisteringan Application

    To unregister your application, use the

    UnregisterMailPackage method. Thisisalso a slot in the

    motorola global frame. You passyour application symbol asa

    parameter with code similar to the following:

    UnregisterMailPackage(kApplicationSymbol);

    The time at which you register and unregister your application will

    depend quite a bit on your particular application. Certainly, youll want

    to register when you expect to receive mail. Different applications,

    however, might want to do thisat different times. Here are some

    examplesof when:

    When your application isopened.

    When your application isinstalled. When you send a message that requiresa reply.

    At specifictimes. Perhapsyour application receivesmail at 10 am

    each day. In that case, you could register an alarm for 9:55 am that

    in turn registersyour application for mail.

    Youll deregister when you no longer expect to receive mail, or when

    your application can no longer receive it. The latter occurswhen your

    application isremoved. Therefore, you should minimallyunregister in

    yourRemoveScript. Asto the former situation, anyof the

    following answersmight be appropriate for different applications:

    When your application isclosed.

    When the mail youre expecting hasfinished arriving.

    At specific times. Perhapsyour application listensfor mail at 10 am,

    but if no mail arrivesby10:15 am, then it wont be arriving at all. In

    that case, you could unregister at 10:15 am.

    In general, you should tryto minimize the amount of time your

    application isregistered. Otherwise, receiving mail can be quite time

    consuming for the user. Imagine the time involved if everyapplication

    alwayslooksat the incoming mail in turn and then passesit on to the

    next application.

    IMPLEMENTINGAMARCOMAIL-BASEDAPPLICATIONNow that you have had an opportunityto get some sense of what is

    involved in creating a mail-based application for the Marco, let uslook

    at a sample application that doesthis.

    AStock Quote Application

    The application well be creating obtainsstock quotesfrom an Internet

    stock information service. The user selectsa stock symbol and taps

    Lookup (see figure 2.3). Thisthen sendsa mail message to an Internet

    addresswhich in turn sendsback information about that stock symbol.

    Thismail message isreceived bythe application, which then displaysit for

    the user in a view(see figure 2.4).

    Note:

    The Internet service we are using for this appli cation, QuoteCom,

    provides stock quotes and other information. They have many levels ofservice, one of which is free and allows up to 5 stock quotes per day. In

    order to receive free quotes, you must have registered for service. For

    further i nformation, including information on registering for free

    quotes, send email to [email protected].

    Returnsnil

    The received Mail Scripts for each registered application

    Each application looks at the incoming mail todetermine if it will handle it

    In

    Box

    Incoming Radio MailFrom: Mary

    To: John

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    5/24

    Newton Technology Journal August 1995

    5

    Figure 2.3 Looking up a stock quote.

    Figure 2.4 Receiving a stock quote.

    Sendinga Stock Quote

    The first thing that needsto be done isto send the request. To

    receive a quote, we must send mail [email protected]

    with the subject Quote symbol. First we create the frame that

    we will send out:

    local mailFrame := {appSymbol: kAppSymbol,connect:true,email: [email protected],hidden: true,text: "", // The text of the message is blanktitle: "Quote" && stockSymbol,

    };

    Now, we call theSend function specifying our newlycreated

    mailFrame and the transport we want to use:

    call kSendFunc with ('mail, mailFrame);

    Note

    The Marco does allow sending frames in mai l messages over i ts

    transports ( just as NewtonMail does). Of course, the receiver of the

    mail must be a Newton in order to do anything with the frame.

    Receivinga Stock Quote

    Next, we must install our application so that it isnotified when mail

    arrives. Although we could do thisin ourInstallScript, that

    would reallybe overkill. Rather, it isbetter to install onlywhen we are

    expecting to receive mail. Thiswayunasked-for mail isnever sent to us;

    instead, mail comesin onlyin response to an outgoing item. Therefore,

    we will install our application to receive mail onlyafter sending a piece

    of mail. Likewise, when our response comeswe will want to deinstall.

    Thisisa little trickier than issounds, however. Here are the situations

    we need to make sure we take into account:

    What i f the user sends another stock lookup before the first has

    returned?

    What i f the user removes the application while there is an

    outstanding request that hasnt been received yet?

    Thus, well also need to keep a count of how manyoutstanding

    requestswe have. When we send a stock lookup request, well

    increment that count. If the count just went from0 to1, well install

    ourselvesfor mail notification:

    numberOutstandingRequests:=numberOutstandingRequests + 1;

    if numberOutstandingRequests = 1 then beginmotorola:RegisterMailPackage(kAppSymbol);

    end;

    At thispoint, the mail hasbeen sent, and our application hasbeen

    registered to receive notification whenever mail arrives. If mail arrives,thereceivedMailScript message issent to our applications

    base view. Thus, we will create thismethod asa slot in our application

    base template, and within it check to see if the incoming mail belongs

    to our application or not. If the message doesnot belong to us, we

    also need to passit along. Here isthereceivedMailScript:

    func(item)begin

    if :IsQuoteResponse(item) then begin:RemoveRequestFromQueue();local error := :GetError(item);if error then

    :Notify(kNotifyAlert,EnsureInternal(kAppName),EnsureInternal(error))

    else beginlocal quote := :GetQuote(item);

    // EnsureInternal because floater may// be open when app is removed

    floater := BuildContext(EnsureInternal(pt_quoteResponseFloater));

    floater:Open();floater:SetResponse(quote);

    end;

    // let's delete the entrysince we saw it...If IsSoupEntry(item) then

    EntryRemoveFromSoup(item);

    return nil;end else // its not our mail

    return item;en d

    In thiscode, we check to see whether the mail isa response to our

    quote request (withIsQuoteResponse). I f it doesnt belong to

    us, we return the item, signifying that itsnot ours. Otherwise, we need

    to take care of all of the following in thiscode:

    Reduce the count of outstanding requests(using

    RemoveRequestFromQueue),

    Deinstall our application from mail notification, if necessary, if the

    count is0 (handled inRemoveRequestFromQueue).

    Read the information from the message. If the information isa valid

    quote, we need to displayit in a floater (inGetQuote).

    If the information isnot a valid quote, we put up a notifyslip

    showing the error (handled inGetError).

    Checkingfor a Valid Quote

    Note that a response to a quote request will have a return address

    of services@ quote.com and a subject of QuoteCom Email

    Response. We look for both of those inIsQuoteResponse:

    func(item)begin

    constant kQuoteFromEMailAddress :="[email protected]";

    constant kQuoteTitle :="QuoteCom Email Response";

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    6/24

    August 1995 Newton Technology Journal

    6

    return StrEqual(item.fromEmailAddress,kQuoteFromEMailAddress) andStrPos(item.title, kQuoteTitle, 0) nil;

    en d

    The text of a valid quote response will look like:

    Tue Feb 7 14:24 EST Quotes may be delayed by exchanges

    Symbol High L o w Last Change

    Volume

    ----------------------------------------------------------------------

    BRK 24600.0000 24500.0000 24500.0000 +50.0000 60

    N a m e Earn/Shr P/E Div/Shr 52-wk Price Range

    ----------------------------------------------------------------------

    Berkshire Hathaway N/A 30.0 0.10 15150.00 - 25200.00

    Handlingan Error

    Well assume that if the text startswith Error: or i f the --- cant be

    found that the response issome sort of an error ( perhapswe arent

    registered with Quote.Com or weve exceeded our number of quotesfor

    the day). Here isthe GetError method which returnsan error message,

    or nil for no error:

    GetError := func(item)begin

    constant kCharactersBeforeQuote := "----\n";

    if BeginsWith(item.text, "Error:") thenreturn item.text

    else if not StrPos(item.text,kCharactersBeforeQuote, 0) thenreturn "Can't find the quote"

    elsereturn nil;

    en d

    Gettingthe Text for a Quote Frame

    We need to extract the information from the quote text and put it

    into a frame containing that information. An example of a desired quote

    frame is:

    {

    name: "Berkshire Hathaway",

    symbol: "BRK",

    high: "24600.0000",

    low: "24500.0000",

    last: "24500.0000",

    change: "+50.0000",

    volume: "60"

    }

    Here istheGetQuote method, which searchesthrough the text

    using brute force alone. The method then, in turn, createsa quote

    frame:

    func(item)begin

    constant kCharactersBeforeQuote := "--\n";local startOfQuote := StrPos(

    item.text, kCharactersBeforeQuote, 0);if not startOfQuote then

    return nil;

    local position := startOfQuote +StrLen(kCharactersBeforeQuote);

    local stuff := {name: "", symbol: nil,high: nil, low: nil, last: nil,change: nil, volume: nil};

    local GetString := func(s, sLength)begin

    local endPos := position;// skip white spaces at the beginningwhile endPos < sLength and

    IsWhiteSpace(s[endPos]) do beginendPos := endPos + 1;

    end;position := min(endPos, sLength - 1);// now skip overwhile endPos < sLength and

    not IsWhiteSpace(s[endPos]) do beginendPos := endPos + 1;

    end;endPos := min(endPos, sLength - 1);local s := SubStr(s, position,

    endPos - position);position := endPos;return s;

    end;

    locallength := StrLen(item.text);stuff.symbol := call GetString with (

    item.text, length);stuff.high := call GetString with (

    item.text, length);stuff.low := call GetString with (

    item.text, length);stuff.last := call GetString with (

    item.text, length);stuff.change := call GetString with (

    item.text, length);stuff.volume := call GetString with (

    item.text, length);

    // name of stock follows after more "---"position := StrPos(item.text,

    kCharactersBeforeQuote, position);if position then begin

    stuff.name := Substr(item.text,position + StrLen(kCharactersBeforeQuote),kNameLength);

    TrimString(stuff.name);

    end;

    return stuff;en d

    Once weve got a quote frame, itsa simple matter to set the various

    static textsin a floater. Here istheSetResponse method of the

    floater which doesthat:

    func(quote)begin

    SetValue(headline, 'text, headline.text &&quote.name);

    SetValue(symbol, 'text, quote.symbol);SetValue(high, 'text, quote.high);SetValue(low, 'text, quote.low);

    SetValue(last, 'text, quote.last);SetValue(change, 'text, quote.change);SetValue(volume, 'text, quote.volume);

    en d

    Handlingthe Unregistration

    The application must be unregistered if there are no more

    outstanding requests. TheRemoveRequestFromQueue

    method doesthat:

    func()begin NTJ

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    7/24

    Wayfarer providesdevelopersa client/server framework on which todevelop Newton applicationsand integrate them into enterprise

    networksand resourcessuch asdatabases, terminal servers, e-mail

    systemsand legacysystems. Wayfarer'sframework, the Wayfarer

    Enterprise Server NT, hidesthe complexityof communicationssoftware,

    so developerscan implement custom applicationsquicklyand run them

    reliablyover mobile networks. Wayfarer-based applicationssupport

    Newton connectivityusing TCP/IP protocolsover most leading wire-line

    and wirelessnetworks.

    Programmersdevelop Wayfarer applicationsusing standard

    languagessuch asVisual Basic , PowerBuilder , Visual C+ + , and

    NewtonScript . Developersuse WayfarersAPIsto create user interfaces

    on Windows PCsor Newton MessagePad PDAs, and to work with

    application logic on the server. The server providesflexible accessto

    multiple enterprise systems, such asdatabases, that can be

    incorporated into mobile applications. Real-time data access,

    transactions, messaging, work flow and other functionscan all be

    integrated into individual custom applicationsfor mobile work forces.

    DESIGNEDFORMOBILENETWORKSWayfarer optimizesperformance over low-bandwidth, high-latency

    mobile networks. The Server offloadsmost storage, computing and

    communicationstasksfrom mobile computersand mobile networks

    onto a powerful server computer and high-bandwidth, fixed enterprise

    networks. Wayfarer supportsmost wire-line and wirelessmedia in local-

    and wide-area networks, used in anycombination.

    Access to Enterprise Systems

    TheWayfarer Server providestoolsto accessand integrate data,

    programsand servicesfrom anystandard or legacysystem. Asa

    distributed computing model, developerscan accessmultiple systems

    simultaneouslyand can integrate them into custom mobile

    applications. Developerscan also use standard toolsfor standard

    systems, such asODBC for SQL databases, or theycan create their own

    tools.

    Communications and Work FlowWayfarerssystem includesextensive messaging, communications

    and work flow support. The Wayfarer Server supportsreal-time

    messaging, alphanumeric paging and e-mail. Messagescan be

    addressed or forwarded to individualsor groupsof users. Using

    WayfarersAPIs, programmerscan easilyintegrate messaging into their

    custom applications. These communicationsfunctionscan also be

    integrated into enterprise systemssuch ascorporate e-mail. Wayfarer

    also supportse-mail over the Internet.

    Integration into the Enterprise

    Wayfarerssystem isbuilt on the leading standardsfor enterprise

    computing, application development and internetworking. The Wayfarer

    Server, and Windowsand Newton mobile clientsall use TCP/IP

    networking protocols. Windowsclientsand the Server also support

    Named Pipes. The Wayfarer System Manager providesa graphical

    interface for system configuration, management and security. All system

    accessand usage isconfigured and controlled centrally. The Wayfarer

    System Manager also communicateswith mobile client usersthrough

    the messaging functionsbuilt into Wayfarerssystem.

    Wayfarersarchitecture optimizesperformance on mobile devicesand

    mobile networksbyoffloading the burden of computation, storage and

    communicationswith enterprise serversonto the Wayfarer Enterprise

    Server. These optimizationsfor mobile environmentsgive rise to the

    server and servicesmodel. A client/server architecture enablesmany

    Newton MessagePadsand Windowscomputersto be connected to a

    single Wayfarer Enterprise Server.

    Wayfarer usesa client/server architecture to connect Newton

    The Wayfarer Enterprise Server NTby Ed Colby, Wayfarer Communications, Inc.

    Server Technology

    Newton Technology Journal August 1995

    7

    wire-line or wireless

    connectivity

    Enterprise systems and servers

    Wayfarer Enterprise

    Server NT (v3.5)

    Wayfarer System

    Manager (WFW 3.11)

    Framework to develop and deploy

    custom applications onWindows mobile computers and

    Newton MessagePads

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    8/24

    August 1995 Newton Technology Journal

    8

    MessagePadsand Windowsmobileclientcomputersto the WayfarerEnterprise Server. Wayfarer relieson TCP/IP protocolsin Newton,

    included in Wayfarersproduct, to provide network connectivity

    between mobile client devicesand the Wayfarer Enterprise Server.

    Theserverfunctionsasa gatewaybetween mobile client devicesand enterprise servers, such asSQL databasesand e-mail systems. It

    managesconnectionsand communicationswith Newton MessagePads

    and Windowsmobile clients, eliminating the need for programmersto

    manage these tasks.

    The Server providesservicesto Wayfarer mobile clients. Wayfarersservicesinclude mail, paging, messaging, and authentication. Using

    enterprise information and communicationsresources, servicesprovidespecific functionalityto Wayfarer client users. Programmerswrite

    programson mobile client devicesthat use and integrate anyor all of

    Wayfarersservicesto meet specific applicationsrequirements.

    Programmersdevelop applicationsbycalling WayfarersAPIsavailable

    through NewtonScript and NTK. The APIsprovide general functionality

    for mobile applications, aswell ascallsfor all servicesavailable from the

    Wayfarer Server. Developersprogram Newton MessagePad applications

    exclusivelyin NewtonScript.

    Wayfarer applicationsdo not have to change to work with different

    connectivitymedia. Byusing TCP/IP asthe network protocol,

    developerscan deploymobile applicationswith anystandard form of

    wire-line or wirelessconnectivityfor in-house, metropoli tan or wide-

    area coverage. Applicationscan be developed with wire-line

    connectivityfor convenience and cost, and can sti ll be deployed with

    wirelessconnectivitymedia. Supported connectivitymedia includes

    land-line and cellular dial-up, CDPD, Metricom, Photonics, Dayna,

    Digital Ocean and RAM Mobile Data.

    Wayfarerssystem includesa Windowsfor Workgroups3.11 program

    called the Wayfarer System Manager; thisprovidesall administrative

    functionalityfor clientsand serverson the Wayfarer system. Wayfarer

    System Manager requiresno programming, but doesrequire

    configuration in setting up a Wayfarer system.

    Programmerscan develop custom servicesusing the Wayfarer

    C+ + /OLE Automation Custom Service Framework. Thisframework allows

    a developer to author custom servicesusing MicrosoftsVisual C+ + , or

    Visual Basic, running under WindowsNT 3.5. Using thisframework,

    developerscan easilycreate servicesthat accessenterprise-specific

    resourcessuch asdatabases. Custom servicesare full-fledged services

    that can be accessed byclient applicationsin the same manner asthe

    built-in Wayfarer services.

    custom apps

    Visual Basic

    PowerBuilder

    built-in services

    authentication

    email

    paging

    real-time messaging

    Wayfarer Server

    engine

    custom

    services

    VB or

    PowerBuilder

    custom

    servicesC++

    Network connection

    Wayfarer

    OLE 2.0service

    framework

    Wayfarer

    C++ serviceframework

    Wayfarer OLE

    2.0 application

    framework

    Wayfarer C++

    DLL application

    framework

    custom apps

    C++

    network connection

    (TCP/IP or Named Pipe)

    custom appsNewtonScript/

    NTK

    Wayfarer

    Newton

    application

    framework

    TCP/IP network

    connection

    Newton

    MessagePad

    Windows

    mobile computer

    Wayfarer Enterprise Server NT

    Windows NT 3.5

    Enterprise systemsdatabases

    email

    terminal and applications servers

    Wayfarer

    System

    ManagerWindows 3.1

    authentication

    configuration

    administration

    messaging

    custom

    developmentWindowsMobile computer

    Wayfarer Enterprise Server NTWindows NT 3.5

    CustomDevelopment

    CustomServicesVB orPower Builder

    built-in services authentication email paging real-time messaging

    CustomServicesC++

    Wayfarer

    OLE 2.0serviceframework

    Wayfarer Serverengine

    Wayfarer

    C++ serviceframework

    TCP/P networkconnection

    CustomAppsVisual BasicPowerBuilder

    CustomAppsC++

    WayfarerC++CLL applicationframework

    WayfarerOLE2.0 applicationframework

    WayfarerNewtonapplicationframework

    CustomAppsNewtonScript/NTK

    NewtonMessagePad

    network connection(TCP/P or Named Pipe) Network connection

    WayfarerSystemManagerWindows 3.1

    authentication configuration administration messaging

    Enterprise Systems databases email terminal and applications servers

    NTJ

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    9/24

    Newton Technology Journal August 1995

    9

    Manylarge companies, universities, and government agencieshaveconsiderable resourcesinvested in large, mainframe-based databases.

    Rather than replacing their existing systemsto take advantage of

    advancesin client/server technology, these organizationscan now

    use a technologycalled middleware to enable PDAs, desktop

    computers, or World Wide Web browsersto create data entry and

    retrieval systemsfor applicationsthat previouslycould be accessed

    onlybyterminal emulators. CEL CorporationsBLACKSMITH isa

    middleware development tool that allowsNewton developersto add

    client/server communicationscapabilitiesto the Newton MessagePad.

    DESKTOP-DRIVENCLIENT/SERVERSTodaymost userscommunicate with mainframesbymeansof terminal

    emulation on PCs. But methodsof interacting with mainframeshave

    changed dramaticallyover the last ten years. With the cost of PC

    processing power at the lowest levelsever, it no longer makessense to

    use PCssimplyfor terminal emulation. Instead, firmsare looking to

    combine the flexibility, ease of use, and power of their personal

    computers including PDAs with the resourcesof their mainframes.

    The interaction between the host computer and the desktop

    computer hasevolved over the years, with the desktop machine taking

    on a greater share of the processing power. Originally, PCswere used

    onlyfor terminal emulation, where the host-based system controlled all

    processing and used the PC onlyfor displaying data or receiving user

    input. In front-ending, or simple automations, character streamsfrom

    the host were mapped to objectsin a graphical user interface or to

    keystroke commandsfor macros, making it easier for the user to interact

    with the host. In host-driven client/server applications, the desktop

    machine became a server capable of receiving messagesfrom the host;

    some of the hostsfunctionalitywasextended to the desktop machine,

    and desktop-based user interface capabili tiessuch asmenusor dialog

    boxeswere possible. With desktop-driven client/server applications,

    logic issplit between the client and the server; however, the desktop

    machine retainsprinciple control of the application and determines

    what should be displayed and how user input should be handled.

    In a desktop-driven client/server scenario, the desktop applicationsubmitsqueriesor updatesto a server on a host or another platform.

    There isa significant increase in system functionalitybecause of the

    improved coordination between stand-alone desktop applicationsand

    the server. Thisapproach allowsserversto be optimized for data-

    management functions, such ashigh-volume transaction processing or

    resource-intensive database queryprocessing, while allowing desktop

    computing power to be utilized more fully. An example of a desktop-

    driven client/server isa fourth-generation language written using

    extensionsthat send information to and retrieve information from

    relational or nonrelational host systems.

    In general, desktop-driven client/server solutions also called

    distributed applications refer to transaction programsthat relyon

    specific client and server componentsdesigned to optimize

    performance and productivity. The server elementsinclude the program

    engine and the management servicesgoverning securityand

    administration. The client software containsthe end-user interface and

    some level of intelligence that might include some local data storage

    error checking and other functions. The model allowsthe two

    componentsto be separated so that each maybe independently

    tailored to specific usersand functions.

    Thiscontrastswith traditional methodologythat hasa central

    department such asmanagement information systems(MIS)

    generating more generic processesthat accommodate manyusers, but

    are inherentlylessproductive and are more difficult to adapt. Shifting

    the burden of data access from a centralized system where MIS

    respondsto departmental needsto a system where departmentsare

    self-sufficient benefitsthe entire organization byallowing each group

    to satisfyitsneeds. Also, development time and costsdecrease when

    similar development functionsare conducted on the PC instead of the

    mainframe.

    Another factor in thismodel isthe distribution of processing power

    acrossthe enterprise. MIS organizationsface the rigorousassignment

    of allocating and managing mainframe resources. Byintegrating the

    intelligence of personal computers, manytraditional mainframe tasks

    such aserror and syntax checking can be handled bydesktop

    systems. Asthe intelligence of front-end systemsevolves, more of the

    information processing occursat the desktop; response time increases

    and use of unnecessarynetwork bandwidth diminishes. In addition, by

    sharing the processing burden acrossthe enterprise, mainframesare

    better uti lized for CPU-intensive applications.

    In thisview of corporate data, all usersshare the cost of the system.

    Departmentscan either allocate fundsto develop custom toolsand

    applicationson the mainframe, or theycan move development to the

    PC. Development toolsfor the PC such asOmnis7, 4th Dimension,

    PowerBuilder, Visual Basic, Microsoft Access, Uniface, Visual AppBuilder,C+ + plusthe introduction of PDAsand Web technology have

    significantlyreduced the investment in time and capital required for the

    development process. Increasingly, departmentsare taking

    responsibilityfor developing their own toolson the PC instead of

    investing heavilyin similar toolson the mainframe.

    BLACKSMITH: A DESKTOP-DRIVENMIDDLEWARESOLUTIONThe growth of client/server applicationsisdue in part to the

    proliferation of a new generation of software development toolscalled

    BLACKSMITH: PDA-Mainframe Communicationsby Russel D. Matichuk, CEL Corporation

    Server Technology

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    10/24

    August 1995 Newton Technology Journal

    10

    middleware.Because no single protocol adequatelysolvesall data

    transmission issues, large companiestend to manage several protocols

    throughout their corporate network. These organizationsare also using

    third-and fourth-generation languages(3GLsand 4GLs) extensivelyon

    microcomputersand are evaluating the use of PDAsand Web technology.

    Thispresentsa number of challenges, especiallywhen end usersneed to

    accessinformation from varioushost systemsemploying differing

    network protocols. BLACKSMITH isdesigned to ease the processofwriting distributed applicationsbyabstracting the detailsof both the

    operating environmentsand the network protocols.

    The keyto improving user productivityisto break down the barriers

    between these distinct environments mainframesand PCs so end

    userscan spend lesstime learning the intricaciesof complicated

    mainframe applicationsand concentrate instead on accessing

    information. If usersrequire data in different locationsor on different

    systems, theyshouldnt have to learn new methodsfor retrieving data,

    but should be able to use familiar front endssuch asPCs, PDAs, or Web

    browsers. Middleware providesa migration path. Network developers

    and support staff are usuallyskilled in developing, maintaining, and

    operating host-based systems, leaving them reluctant to embark on a

    distributed-solution development. Thus, a middleware product isonly

    viable for them if presented in an architectural framework that provides

    a slow migration path, enabling them to preserve their legacy

    investments, while graduallyincreasing the use of desktop and local

    server computing resources. Several factors operational savings

    resulting from integrating desktop systems, the abilityto create

    scalable systems, and a reduction in development and deployment time

    should make distributed systems(desktop-driven client/server

    systems) increasinglyattractive to network developers.

    There are several waysof providing a communicationslink between

    a client and a server. The method that BLACKSMITH usesiscalled

    Terminal Data Stream (TDS) communications. The TDS isthe physical

    connection that allowsan operator to communicate with host

    computers; it includesdata streamsof all types(3270, 5250, VT100, etc.) .

    Initially, onlydumb terminalswere connected through the TDS. With

    the advent of terminal emulators, microcomputershave since

    dominated the use of the TDS communicationsmedium.

    The keytechnologythat spawned the terminal emulation industry

    and which isthe critical ingredient in the recent explosion of

    development using client/server technology isthe development of

    theterminal emulator API(Application ProgrammersInterface). In an

    effort to expand their market, vendorsof terminal emulation products

    wrote APIsthat allowed third partiesto create and sell software that

    depended on these products. However, these APIsare fraught with

    deficiencies. Theywere written to allow integration onlybythird-

    generation languageslike C, are verydifficult to use, and in most casesprovide onlyverybasic services. None of theAPIsprovidesa reliable

    host-state management process. In addition, each vendorsAPI isquite

    different from those of other vendors.

    BLACKSMITH isdesigned to eliminate the complexitiesof

    connecting microcomputer applicationsto host systems. With terminal

    emulator APIsor communicationsstandardssuch asVT100, developers

    must have advanced communicationsprogramming skills; with

    BLACKSMITH, developersarent required to know anything about the

    low-level communicationsissues. Theycan choose from a wide

    selection of third-and fourth-generation development toolsto build

    applicationsthat improve the data entryand retrieval processesused

    bytheir organization. In addition, developerscan implement solutions

    that include PDAsor Web browserscommunicating with a BLACKSMITH

    server. One set of BLACKSMITH commandscan be used in anyof the

    environmentsthat are supported. Thissame set of commandswill

    allow a developer to write applicationsthat communicate with any

    host system, using anyof the communicationschannelsthat are

    supported.

    USINGBLACKSMITHWITHNEWTONSANDTHEWORLDWIDEWEBBLACKSMITH 2.0 addsNewton and Web client accessto mainframesand

    minicomputers. Organizationscan now have their staff interacting with

    their host systemsusing graphical Macintosh, Windows, Newton, or

    Web applications, with no modification to the mainframe or

    minicomputer applications.

    Using NewtonScript or HTML (Hypertext Markup Language) Web

    server code, BLACKSMITH developerscan build functionsthat send a

    Remote Procedure Call(RPC) to a waiting BLACKSMITH server. The RPC is

    written using one of the Macintosh or Windows4GLsor 3GLsthat

    BLACKSMITH supports: PowerBuilder , Visual Basic , Omnis7, 4thNTJ

    To request information on or an application for ApplesNewton developer programs,

    contact ApplesDeveloper Support Center at 408-974-4897

    or Applelink: DEVSUPPORT or Internet: devsupport@ applelink.apple.com.

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    11/24

    Newton Technology Journal August 1995

    11

    In NewtonScript, function objects( sometimescalled closures) are first-classobjectswhich can be manipulated and stored just like other

    values. For example, you can store a function object in:

    a local variable

    an array

    a slot in a frame

    a soup entry

    You can use function objectsin a varietyof waysaswell: you can

    passa function object asa parameter, Clone it, or DeepClone it. This

    consistencybetween function objectsand other valuesmakes

    NewtonScript veryflexible.

    These aspectsof function objectsare usuallywell understood by

    NewtonScript programmers. There isanother aspect to a NewtonScript

    function object, however, that islessclear:

    when a function object iscreated, byexecuting a func statement,

    it savesthe environment that existsat that time.

    Bydoing so, the function object can have accessto local variables,

    parameters, and inherited variable lookup that existed at itscreation

    time.

    The term function object, rather than just function, isused to

    emphasize the fact that onefunc statement can give rise to many

    different function objects. These functionswill differ based on the

    environment that existsat the time thefunc statement isexecuted.

    THEFUNCTIONENVIRONMENTTo understand how you can use thisaspect of a function in your

    applications, let usfirst review the environment of most NewtonScript

    functions. Usually, you create function objectsat compile time. Theyare

    slotsin a template, edited using a slot browser, or theyare functions

    created in a Project Data file. In either case, the environment that exists

    isthe environment of NTK. Thus, there are no local variables,

    parameters, or inherited variablesavailable when that function object is

    created.Now, look at a different wayto create a function object. In thiscase

    the environment in which it iscreated will be significant. Thiswill be a

    run-time function object. Please note that bydefinition, these will be

    nested functions(onescreated inside other functions) .

    Here isan example:

    outerFunction := func(aParameter)begin

    local aVariable := 3;

    local nestedFunction := func(nestedParameter)

    beginlocal nestedlocal := 5;

    Print(aParameter);Print(aVariable);Print(nestedParameter);Print(nestedFunction);Print(nestedlocal);

    end;

    The function object, nestedFunction, iscreated as

    outerFunction isexecuting. At the run-time point when

    nestedFunction isactuallycreated, the environment includes

    a local variable, aVariable, and a parameter,aParameter.

    SincenestedFunction hasaccessto that environment, it can

    accessboth itsown parametersand locals, aswell asthose of the

    function in which it isnested.

    HOWFUNCTIONOBJECTSARECALLEDBefore we actuallytalk about how you can use function objectsin your

    programming, we need to addressthe manner in which you call a

    function object. There are four waysyou can do this:

    With a compile-time argument list (Call):

    Call functionObject with (argumentList)

    With a run-time argument list (Apply):

    Apply(functionObject, argumentArray)

    Bysending a message with a compile-time argument list (:and:?):

    frameExpression:message(argumentList)

    Bysending a message with a run-time argument list (Perform):

    Perform(frameExpression, messageSymbol, argumentArray)

    Here issome sample code that usesthese four ways:

    local Pow := func(num, iterations)

    beginfor i := 1 to iterations dototal := total * num;

    return total;end;

    Call Pow with (2, 3) 8

    local argArray:= [2, 3];Apply(Pow, argArray) 8

    local account := {balance: 0,Deposit: func(amount)

    return balance := balance + amount,

    Function Objectsin NewtonScriptby Jul ie McKeehan and Neil Rhodes, Calliope Enterprises, Inc.

    NewtonScript Techniques

    1995, Apple Computer, Inc. and Calliope Enterpri ses, Inc.

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    12/24

    August 1995 Newton Technology Journal

    12

    };

    account:Deposit(50) 50Perform(account, 'Deposit, [75]) 12 5Print(account) {balance: 125,

    Deposit: }

    HOWFUNCTIONOBJECTSCANBEUSED

    The sectionsthat follow describe a several waysthat you might usefunction objects. Two examplesare:

    to implement abstract data types

    to support Date Find operations.

    Abstract DataTypes

    One use of function objectsisto implement abstract data types.

    These are typesthat can onlybe modified procedurally; their actual data

    ishidden. Though it might appear so, frameswith methodsdont

    provide the same functionality. In a frame, the data valuesin the slots

    are visible and can be modified even when not using the appropriate

    methods.

    Consider the following account generator:

    MakeAccount := func()begin

    local balance := 0;local Deposit := func(amount) begin

    return balance := balance + amount;end;return Deposit;

    end;

    CallingMakeAccount returnsa function object:

    myAccount := call MakeAccount with ()

    Thisfunction object referencesthebalance local variable from

    MakeAccount. Even thoughMakeAccount isno longer

    executing, since the nested function, Deposit, references

    balance, thebalance variable continuesto exist. Thus, calling

    myAccountmodifiesthe hidden variablebalance:

    call myAccount with (50) 50call myAccount with (75) 10 0

    Notice also that one function object can return multiple function

    objects, each of which referencesshared data. For instance, suppose

    you want both Deposit and Clear capabilitiesin your account:

    MakeAccount := func()begin

    local balance := 0;local Deposit := func(amount) begin

    return balance := balance + amount;end;

    local Clear := func() beginbalance := 0;

    end;return [Deposit, Clear];

    end;

    Because MakeAccount needsto return two values(two function

    objects), it returnsthem in an array:

    myAccount := call MakeAccount with ();myOtherAccount := call MakeAccount with ();

    call myAccount[0] with (50) 50

    call myOtherAccount[0] with (40) 40call myAccount[0] with (75) 12 5call myAccount[1] with () 0call myOtherAccount[1] with () 0

    Using an arrayfor the two function objectsissomewhat

    inconvenient, however, since the numbers0 and 1 dont describe the

    Deposit andClear functionsin a veryuseful manner. To fix this

    problem, we will rewriteMakeAccount to return the two functionobjectsin a frame rather than in an array. Thisway, the function objects

    can be referenced byname, rather than byarraylocation.

    MakeAccount := func()begin

    local balance := 0;local d := func(amount) begin

    return balance := balance + amount;end;local c := func() begin

    balance := 0;end;return {

    Deposit: d,Clear: c,

    };end;

    myAccount := call MakeAccount with ();

    call myAccount.Deposit with (50) 50call myAccount.Deposit with (75) 12 5call myAccount.Clear with () 0

    Remember, however, that we are using the above frame onlyasa way

    to store two named values. We have not started using anyobject

    programming, however, asno messagesare being sent.

    Admittedly, thisuse of function objectsto create Abstract Data Types

    isnot common. There are cases, however, where function objectsare

    necessaryin your Newton programming. One of the most common

    examplesoccurswhen an application issupporting Date Find.

    UsingFunction Objects to Support Date Find

    Here isan excerpt of code from DataFind:

    func(comparison, time, )begin

    cursor := Query(, {type: 'index,validTest: func(e)begin

    if comparison = 'dateBefore thenreturn e.date < time

    elsereturn e.date > time;

    en d});return cursor to caller

    end;

    Even though thevalidTest function isembedded in the cursor,

    it iscalled from the Find resultsslip to displaythe found entries. Notice

    howDateFindscomparison and time parametersare used bythe

    nested functionvalidTest. Keep in mind that thevalidTest is

    called after theDateFind function hasfinished executing.

    Here isanother example of how you might use function objects.

    Imagine that you want to count the number of entriesthat are in a

    particular query. In such a case, you might use a function object to

    count the number of entriesin a cursor using MapCursor:

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    13/24

    Newton Technology Journal August 1995

    13

    CountEntries := func(cursor)begin

    local total := 0;MapCursor(cursor, func(e)

    begintotal := total + 1;return nil;

    end);return total;

    en d

    The function object passed toMapCursor incrementsa variable

    inCountEntries. Notice that the function object returnsnil, and

    thusMapCursorwill end up returning an emptyarray.

    STACKFRAMES/ACTIVATIONRECORDSIn most programming languages, when a function isentered, an

    activation record ( also called a stack frame) ispushed on the stack. This

    activation record containsthe parametersto the function and local

    variables. When the function returns, the activation record ispopped

    from the stack.

    For NewtonScript, some allowance needsto be made for variables

    which are closed over; that is, variableswhich are accessed bynested

    functions. Since nested functionsmayneed to accessvariablesfrom

    outer functionseven after the outer function hasexited, a stack-based

    system which alwayspopsouter referencesfrom the stack would fail.

    One possible implementation could be to allocate activation records

    in dynamicmemory(the heap).

    Like all other allocated memory, when no more referencesare made

    to the memory, it can be garbage collected. Thus, the activation record

    isnot freed when a function object exitsif anynested functionsstill

    exist. Onlywhen all nested functionsare freed isthe activation record

    available for garbage collection.

    Another implementation might store part of an activation record on

    the stack, and part on the heap (onlythose variablesreferenced by

    nested functionsneed be on the heap) .

    MESSAGECONTEXTASPARTOFFUNCTIONOBJECTA function object hasaccessto more than local variablesand

    parametersfrom enclosing functions. It also hasinheritance lookup

    based on the value of self at the time the function object wascreated.

    Thismeansthat a function object hasaccessto all variables, including

    inherited slots, that are available to the code that created the closure.

    Thisinheritance lookup isimplemented bystoring a message

    context aspart of a function object. Thismessage context containsthe

    value of self at the time a closure iscreated. Calling a closure restores

    self to the value stored in itsmessage context.

    The major difference between calling a closure and sending amessage isthat sending a message setsthe value of self to the frame

    where the message issent. Thus, sending a message causesthe

    message context of the closure to be ignored.

    UsingInheritance in a Function Object

    There are times, however, when you need to use inheritance in a

    function that hasnot been executed in response to a message send. A

    common case of thisin Newton programming isfound in the

    implementation of filing. Filing isusuallyimplemented bycreating a

    cursor that containsavalidTest. The cursor isusuallycreated

    when the application opens:

    app.viewSetupFormScript := func()begin

    self.theCursor := Query(, {type: 'index,

    validTest: func(e)

    beginreturn labelsFilter = '_all orlabelsFilter = e.labels;

    end,});

    en d

    The cursor savesthevalidTestcursor and callsit everytime the

    cursor ismoved. When thevalidTest iscalled, thelabelsFilter

    variable islooked up first asa local, and then using inheritancebased

    on the value of self at the time the validTest function object was

    created. Since self wasthe application view when thevalidTest

    wascreated, self isset to the application base view when the

    validTest iscalled.

    Sending a Message Changes the Message Context

    Thus, the major difference between sending a message and calling a

    functionhas to do with the value of self. When a message issent, self is

    set to the frame that wassent the message. When a function iscalled

    directly, self isbased on the message context of the function object.

    FUNCTIONOBJECTSCREATEDATCOMPILETIMEFunction objectscreated at compile time have no lexical environment or

    message context. When a top-level function object iscreated at compile

    time either asa slot in a template editor, or in the top-level of the

    Project Data file the lexical environment and message context are

    empty(Technically, the lexical environment and message context exist,

    but are nil'ed out after the function iscreated). Thisisimportant for

    you to remember when you are creating standalone closures(ones

    which have no referencesto your package). Examplesof such closures

    are those copied to a soup, or the one used asa postParse routine for

    Intelligent Assistance. If you use a closure that hasa non-empty

    message context here, the whole receiver will be copied into the soup

    (or into memoryin the case of Intelligent Assistance). Thisisnot a good

    idea, in most cases. Thus, for function objectswhich need to execute

    independentlyof your package, make sure theyare created at compile-

    time, rather than runtime.

    SUMMARY

    In NewtonScript, function objectsare first-classobjectswhich haveaccessto the environment that existsat the time theyare created. They

    have accessto variablesin enclosing functions, aswell asto inherited

    slotsbased on the value of self at the time the function object was

    created. Because of these characteristics, you can do particular types

    of thingswith function objectsthat can not be done in most other

    languages.

    NTJ

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    14/24

    August 1995 Newton Technology Journal

    14

    Newton Developersnow have accessto a full suite of Newtondeveloper support options, with just announced new programs, and

    enhancementswith reduced pricesto existing programs. Newton

    developersmaychoose from a range of support programs, from self-

    support to unlimited prioritysupport, offered through the Apple

    Developer Group. Our goal isto help you succeed in your

    development efforts so we have delivered programsthat provide you

    with the level of support you need, at a cost you can afford. Read on

    for more detailson new programsand reduced program pricing!

    THENEWTONASSOCIATESPROGRAMIntroduced in December of 1994, thisprogram hasbeen designed as

    the development support option for developersseeking low-cost, self-

    help development resourcesfor Apple'sNewton technology. Primary

    program featuresinclude accessto on-line technical information, Q&As,

    updatesto Newton development tools, the Newton Developer Mailing,

    the Newton Developer CD, discountson Newton developer training

    classes, Apple hardware purchase discounts, and a full suite of

    developer assistance from the Apple Developer Support Center. A full

    featureslist follows.

    Annual membership feesare $250, reduced from $400 in Mayof 1995.

    Associates ProgramFeatures:

    The Newton Orientation Kit

    Newton Developer Mailing

    -Newton TechnologyJournal

    -Newton Developer CD

    -Newton Development Tool Updates

    -Utilities

    -Q&A's

    -Sample Code

    -User Interface Guidelines

    -Apple Directions $200 worth of Discountson Newton development training classes

    Members-onlyaccessto the Newton area on Apple'son-line service

    Discounted ratesfor Apple'sonline Service

    Developer Handbook

    Developer Support Center resources

    Development hardware purchase privileges

    Worldwide Developer Conference invitation

    Newton Developer Conference invitation

    Third-PartyCompatabilityTest Lab

    NEW: THENEWTONASSOCIATESPLUSPROGRAM

    Thisnew program, announced in May, 1995, providesdeveloperswho

    need a limited amount of code-level support an option other than

    purchasing the unlimited support available in the Newton Partners

    Program. Developersreceive all of the same self-help featuresof the

    Newton AssociatesProgram, plusthe option of submitting up to 10

    development code-level questionsto the Newton SystemsGroup DTS

    team via e-mail.

    Annual feesfor the Newton AssociatesPlusProgram are $500 and

    includesthe following features:

    Newton Associates Plus ProgramFeatures:

    All of the featuresof the Newton AssociatesProgram

    Up to 10 code-level questionsvia e-mail

    THENEWTONPARTNERSPROGRAMThe enhanced Newton PartnersProgram boastsan even further

    reduced price and enhanced support features. The improved program

    includesall of the featuresof the Newton Associatesprogram, plus

    unlimited expert-level programming support directlyfrom Newton

    SystemsGroup engineerson the Newton platform via e-mail. Additional

    featuresinclude more hardware purchase privileges, and select

    participation in Apple-sponsored marketing activities, all available at a

    reduced price.

    Annual feesare $1500. Membersof both the Macintosh Partners

    Program and the Newton PartnersProgram will now receive a discount

    of $1000 off the combined membership fees, making dual platform

    support optionseven more affordable than ever before.

    Newton Partners ProgramFeatures:

    All Newton AssociatesProgram Features

    Unlimited Newton programming-level support via e-mail

    Additional discountson development-related Newtons Consideration asa test site for pre-release Newton products

    Select participation in Apple-sponsored marketing activities

    While these programsare for US and Canadian Newton developers,

    manyEuropean developer groupswill be follwing with similar programs

    and pricing structures. European developersshould watch for more

    information and detailson Newton programs. US and Canadian

    developersmayobtain additional information and applicationsfor the

    Newton Developer Programsbycontacting the Apple Developer

    NewChoicesand Reduced Priceson Newton Developer

    Support Programsby Lee Dorsey, Apple Computer, Inc.

    Developer Group News

    NTJ

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    15/24

    Newton Technology Journal August 1995

    15

    asfollows:

    1. Processthe data for use on the Newton2. Create the interface

    3. Build and test the package

    4. Refine the interface and data

    5. Test the product

    6. Build the final product

    Step 1 can take quite a bit of time. A developer mayoften have a large

    amount of data that needsto be processed into data structuresthat

    can be used bya NewtonScript program, aswell asthe need to create

    indexesor other meta information that can be used to accessthe raw

    data. Whether thispreprocessing step occurson the Newton or aspart

    of the NTK package build, it maywell be quite a slow process. Itsnot

    uncommon for thisstep to take 10 minutesor more for a large amount

    of data, and adding 10 minutesto each compile/load cycle can

    drasticallycut your productivity.

    Steps2, 3, and 4 are an ongoing process. Usuallya developer would

    start bycreating a simple interface for testing the data. Then the

    interface would be progressivelyrefined. Note that each

    compile/download of the interface will have the overhead of recompiling

    and reprocessing the data; that means10 or more minutesper iteration

    that could be better spent hacking instead of making coffee.

    Once the product hasbeen refined to a state that matchesthe

    original goals, the developer can proceed to step 5. Note that testing

    will probablyrequire more changes, which meansthat each testing

    revision requiresanother 10-minute wait. You could easilywaste several

    daysworth of prime programming time waiting for those

    compile/download cycles.

    Once the testing iscompleted and all those off-by-one errorshave

    been fixed, you can build the final version of the product.

    A BETTERWAYItsclear from the previousdiscussion that those long

    compile/download cyclesare a time sink. A better approach would be to

    split the application up into logical partsso that you compile and

    download onlywhat you need.

    The most obvioussplit in our map application isbetween the data

    and the interface. Massaging the data takesa significant amount of time

    on each build, so it would make sense to build the data onlywhen ithaschanged. You can do thisbysplitting your application into two

    parts: the data in one part, and the interface in another. Each part

    workswith the whole, but each isin a package of itsown.

    continued from page 1

    Small Parts: A Faster Wayto Develop Large Applications

    MonolithicPackage

    Static Data

    Interface

    Separate

    Packages

    Static DataPackage

    InterfacePackage

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    16/24

    August 1995 Newton Technology Journal

    16

    because yourInstallScriptneedsto get at some object that isnt

    created until later in the build. You can still include a Project Data file

    earlyin the build order that includesall the project-wide constants,

    globals, or functionsyou need, but now you can add a text file named

    something like Install & Remove Scripts at the end of the build order

    to define these scripts.

    Itsmuch easier to create multi-part packages. If a package from

    another project isincluded in the project file, all the partsfrom the

    included package will be copied into the resulting package when the

    project isbuilt. The build order isconsidered: if the included package is

    first, the partsit containsare output first; if the package isincluded at

    the end, the partsit containsare output after the part produced bythe

    current project.

    Layout Improvements

    The first thing youll notice isthat the floating palette that

    accompaniesthe Layout window issignificantlysmaller. Onlythe most

    frequentlyused protosare on the palette itself, which meanstheresa

    much better chance youll be able to remember what all the iconsare. All

    the protosare still available in the pop-up menu on the palette.The new layout windowsare much better about view justification, so

    the rectanglesyou see in the layout window now more closelymatch

    where the windowswill appear on the Newton. (Tip: The rectangle

    showswhere the outside of the viewsborder will be; the inner corner

    markersshow the cornersof the viewsvisible area.)

    continued from page 1

    Taking Advantage of Newton Toolkit 1.5

    A typical wayto include a static data structure in an application isto

    define a constant and then reference that constant. In thiscase, you

    might see something like:

    // In aproject text fileDefConst('kMyStaticData, call BuildMyDataFunc with ()) ;...// and somewhere in the application, we use myStaticDataval := ArrayPos(kMyStaticData, targetKey, 0, nil);

    When you use thismethod, the static data isan integral part of the

    project; however, thismeansthe data must be compiled and

    downloaded each time the project isbuilt.

    An alternative isto create a separate package for the data, and

    reference that data through a well known path. In the simplest

    implementation, you could build another form part and put the staticNTJ

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    17/24

    Newton Technology Journal August 1995

    17

    Finally, the two common screen sizesare readilyavailable in the

    Layout preferences. (These are 240x336 for the Original Apple

    MessagePad, MessagePad 100, and Sharp ExpertPad, and 240x320 for the

    Apple MessagePad 110, Apple MessagePad 120, and Motorola Marco.)

    You can sti ll enter your own sizesto see what your application would

    look like on a wristwatch-or whiteboard-sized Newton product.

    Browser ImprovementsDevelopersspend most of their time working in the Browser

    window, so double-clicking a layout fi le in the project window now

    opensa browser instead of the graphical layout. -B still opensa

    browser aswell, and layout windowsare opened with -L. Once in a

    browser, it takesjust a single click to open an editor on a slot. Youll

    find all of the browser-related menu items, including Browser

    Preferences, in the Browser menu.

    TheText editor type isno longer required. Editing text slotsisnow

    done bydefault in a standard Evaluate editor, so youll have to include

    double quotesfor string literals. Thischange allowsyou to easilyuse

    constantsor compile-time code for text slots, which aidsin localization.

    TheText editor type isstill available for compatibility. (Tip: Turn on

    Show Slot Values to see the type of each editor in the browser

    window.)

    Search

    The List feature of NTK 1.0.1 hasbeen extended into a useful project-

    wide search that letsyou quicklylocate views, slots, or text in slots. In

    NTK 1.5, searching ismuch faster and includestext files. The resultsare

    displayed in a list window; double-clicking on a line in that window will

    take you to a browser or editor with the result selected.

    Error Reporting

    The same location featuresused in Search are also used when an

    error occurswhile building. NTK displaysa dialog box with the error

    message, addsthe text of the error to the inspector window, and then

    highlightsthe line or lineswhere the error occurred, using an open

    browser if one isavailable. Compile-time warnings(such asusing a

    global function that NTK doesnt recognize) are displayed in the

    inspector window only.

    Print Formats, User Protos, Layouts, and Constants

    Print Formatsasa special subclassof layoutsare no longer

    necessary, so you wont find them in the Newmenu. A print format file

    wasspecial in two ways: it wascompiled first and it produced a variable

    so you could reference it in your application. Now you can put a layout

    file anyplace in the build order, and templatesfrom all layoutsare made

    available asdescribed below, so print formatscan be replaced withstandard layouts.

    Here layout meansboth proto templatesand layouts. The only

    difference between a proto template and a layout in NTK 1.5 isthat the

    proto template filesin the project will be available in the layout palette

    asuser protos.

    A new function calledGetLayout isprovided to accessthe

    templatesfor layoutsthat have been compiled byNTK. GetLayout

    takesthe name of the layout file asan argument, and evaluatesto the

    template produced. GetLayoutwill not force the layout to be

    compiled; youll have to change the order in the project window to fix

    file dependencies, butGetLayoutwill generate an error if the

    layout hasnt been built yet.

    Asin NTK 1.0.1, everylayout, print format, or user proto compiled

    also causesa constant to be created for the template produced. This

    constant, calledlayout_thefilename, iscreated assoon as

    the layout iscompiled. However, GetLayout isthe preferred

    method for getting at the template, because of the additional errorchecking it provides.

    You must passGetLayout a constant argument (a string literal

    or a constant containing a string). GetLayout isconstant folded

    (see the following section), so you can safelyuse it in the bodyof a

    function such asviewSetupChildrenScript, asshown in

    thisexample:

    viewSetupChildrenScript: func()begin

    self.stepChildren := [GetLayout(My Special Proto)];end;

    Constant Folding

    Some expressionshave onlyconstant elements, so theycan be

    evaluated asa function iscompiled without changing the behavior of

    the program. Thisprocessiscalled constant folding, and NTK will now

    do thisfor some expressions. For example, in previousversionsof NTK

    the expression2+2 in a function bodywould produce code to add 2

    and 2 at run-time. With NTK 1.5, thisexpression will be evaluated during

    the build and the constant4 will be substituted. ( More practical

    exampleswould be the folding ofvjParentCenterH +

    vjParentBottomV forviewJustify, orvClickable +

    vGesturesAllowed + vNumbersAllowed for

    viewFlags.)

    Frame and arrayaccesscan be constant folded, if the frame or array

    being accessed isa constant. Consider the following constant frame:

    constant kUninvitedGuests := {thingOne: A cat,thingTwo: A hat,

    }

    If a function included the expression

    kUninvitedGuests.thingOne, the stringA catwould

    be substituted bythe compiler.

    More Constants

    NTK 1.5 providesmanymore constantsthat allow your code to take

    advantage of the current compiler settingsand other valuesstored

    with the project file.

    The commonlyused constantskAppSymbol, kAppString,kAppName, andkPackageNameare nowdefined byNTK

    from the varioussettingsdialogs. I f your project alreadydefinesthese

    constants, an error will occur during building when the constant is

    redefined. The old definition will be highlighted, and can easilybe

    deleted. I f for some reason you wish to keep the old constant

    definitions, the NTK 1.0 build rules switch in Project Settingswill make

    NTK skip creation of these constants(among other things).

    kDebugOn isset totrue ornil depending on the state of the

    Debug build flag. kProfileOn will betrue if compiling for

    profiling.kIgnoreNativeKeyword isset if the Ignore native

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    18/24

    August 1995 Newton Technology Journal

    18

    keyword value ischecked; thiswill be discussed further later in this

    article. (ThedebugOn constant from NTK 1.0.1 isalso set; it always

    matcheskDebugOn.)

    Localization Support

    Some featureshave been added to make it easier to localize

    applicationsfor other languages. You define whatscalled a Localization

    Frame, which containsall the strings, bitmaps, or other data that needsto change based on the target language. To use localized information,

    you useLocObj, which will look up the appropriate information

    based on the currentlyselected language.

    Since most developerswill be starting with English projects, the

    English information isprovided asa first argument to theLocObj

    function. For example, if you had atitle slot in your applicationsbase

    view with the stringA Demo Application, you might

    change the contentsto this:

    LocObj(A Demo Application, baseview.title)

    When you have English selected asthe language in the Project

    Settingsdialog, LocObj simplyevaluatesto itsfirst argument, so

    youll still get the stringA Demo Application in thetitle

    slot.

    When some other language isselected, LocObjwill use the

    second argument asa path expression to find the information in a

    localization frame. The localization frame containsa single slot for each

    language, and the path expression isapplied to that slot to find the

    information. To specifythe localization frame, you call the compile-time

    functionSetLocalizationFrame . Here isa partial localization

    frame for French and German:

    SetLocalizationFrame({french: {

    baseview: {title: Un Logiciel de Dmonstration,

    }, german: {

    baseview: {title: Ein Versuchsprogramm,

    }, });

    When the language isset to French, LocObjwill evaluate to the

    stringUn Logiciel de Dmonstration; for German, the

    stringEin Versuchsprogrammwill be used.

    LikeGetLayout,LocObjmust be passed constant arguments

    because it isconstant folded. I tsfine to useLocObj inside any

    function.

    Inspector Improvements

    Youll notice a button bar along the top of the inspector window.The first button allowsyou to connect or disconnect the inspector

    from the Macintosh end without closing the window. The rest provide

    easyaccessto debugging featureslikePrintDepth,

    BreakOnThrows, StackTrace, andExitBreakLoop.

    There isalso a button to set the global variabletrace tonil (this

    button wasat the bottom of the inspector in NTK 1.0.1).

    The inspector output when an exception occursat run-time ismuch

    prettier. The list of known exceptionshasbeen extended, so youre less

    likelyto need to look up error codes, and the exception symbol and allthe exception data are displayed for those unusual cases. The output

    fromStackTracehasalso been made much more readable; only

    information that isrelevant to debugging isdisplayed.

    SETTINGSANDPREFERENCESLooking through the Project menu, youll find three newdialog boxes

    that give you a lot more control over the wayNTK buildsyour project and

    what i t builds.

    Project Settingsgivesyou control over the aspectsof the build-time

    environment for the project. You can choose the platform file from a list,

    and choose the language that appliesto theLocObj function. Here

    you will also find several switchesfor the compiler, including controls

    for debug builds, profiling builds, the native compiler, and a

    compatibilityoption for old projects.

    Package Settingsgivesyou control over the package-wide

    paramatersof the build, such asthe user-visible name of the package,

    version number, and copyright message. Copyprotection and

    compressionsflagsare here, aswell asthe flag that tellsNTK to delete

    the old package when downloading a new one. One new flag isthe

    Auto remove package setting. Thisisonlyuseful with packagesthat

    contain auto parts, since it causesthe package to be removed

    immediatelyafter theInstallScript for the partsisrun.

    Output Settingsletsyou choose what the project produces. The

    default isstill an Application, or form part. If you choose thispart type,

    youll be able to edit the name for the extrasdrawer, application symbol,

    and icon. I tsnow easier to create more than just applications, which is

    to saypart typesother than form parts. The Output Settingsdialog has

    radio buttonsfor auto, book, and store parts, and isextensible.

    BuildingBooks

    NTK 1.0.1 produced book partsif you included a book file in the

    project. In NTK 1.5, book files(produced with the BookMaker

    application) are added like anyother text fi le, and you must choose the

    Book part option. NTK 1.5 now letsyou type in a name, symbol, and

    icon for the book parts. Normallythisinformation comesfrom the book

    file, but if, for example, no icon isfound in the book file, NTK will use the

    one in Output Settingsinstead.

    Auto Parts

    Auto partsare now easier to create. These parts, which do not

    appear in the Extrasdrawer, can be selected in

    the Output Settingsdialog. The name, symbol,

    and icon settingsare not relevant to auto parts,

    and so are disabled. Auto-dispatch auto partsare

    created bychoosing an auto part and selecting

    the Auto remove package option in the Package

    Settingsdialog.

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    19/24

    Newton Technology Journal August 1995

    19

    Store Parts

    NTK 1.5 now allowsyou to create package-based stores, called store

    partsor sometimessoup parts. Choosing Store part makesa compile-

    time global variable calledtheStoreavailable. The functions

    available on thisstore are just like the onesfor the internal or card

    storesat run-time. During build time you create soupson

    theStore, then add indexesand entries. Itsimportant to give this

    store a name thatsbased on your registered signature for example,theStore:SetName(Demo:PIEDTS). When the part is

    downloaded, the package-based store and the soupson it

    becomesavailable through a pair of global functions.

    GetPackageStore takesthe store name and returnsthe store

    object contained in the part, andGetPackageStores returns

    an arrayof storesfor all store partsinstalled.

    You cant do much with package-based storesin the current

    Newton OS. Theyare read-only, and soupson them cannot participate

    in soup unionswith soupson other stores. While you mayconsider

    using them for the convenient indexing that soupsprovide, you

    should keep in mind that soupsare often not the most compact or

    efficientlyaccessed data structuresfor read-onlydata. Usuallya

    collection of arraysor frameswill be more efficient for read-onlydata.

    (See the article Lost in Space available on the CD, AppleLink, and via

    ftp for more details.)

    CustomParts (Fonts, Dictionaries)

    With the Custom Part feature and some toolswhich will become

    available around the same time asNTK 1.5, building custom fontsor

    recognition dictionariesispossible. I f you choose Custom Part, you

    must specifythe part type and the part contentsyourself. The part type

    isentered in the small field next to the Custom Part radio button, and

    the part contentsare entered in the field labeled Result. Commonlyyou

    will create a global frame or arrayin a text file, add data to it in other

    text or layout files, and then enter the global variable in the Result field.

    Thiswill include all objectsreferenced bythe variable in the custom

    part. ( You could also type everything into the tinyResult field, or use

    theLoad orReadStreamFile functionsto read in data, but

    these approachesdont take advantage of anyof the nice featuresof

    NTK Projects.)

    StreamFiles

    You can take advantage of NTKsnew stream file feature to speed up

    building some projects, especiallythose that include large data

    structuresthat dont change veryoften. For example, part number,

    price, or phone listswould be excellent candidatesto place into a

    separate stream project.

    MakingaStreamFile

    A stream file containsone NewtonScript object, but thiscan be a

    frame or arrayso in effect multiple objectscan be included. Lets

    consider, for example, a database of employee names, phone numbers,

    and office locations. The data might be stored in three separate arrays,

    with each arraysorted bythe employee name. For example:

    namesList := [Anderson, Bob, Walthrop, Royce, ...];phonesList := [315 555-4476, 419 555-3543, ...];cubesList := [PPR 51, CL-217, ...];

    (Tip: The NS arrayconstructor isslow for verylarge arrays, so its

    better to create them thisway:names := Array(1000);

    names[0] := Anderson, Bob; names[1] :=

    Walthrop, Royce, ...)

    Store the three arraysin a single object byputting referencesto

    them in a frame:

    output := {

    kNames: namesList,kPhones: phonesList,kCubes: cubesList,

    };

    All thistext isput in a text file (or several text files) and added to a

    project in NTK.

    Specifythat the stream file should contain thisdata bygoing to the

    Output Settingsdialog, selecting the Stream File radio button, and

    typingoutput into the resultswindow. ( We could have simplytyped

    the frame right there, but byusing a single global variable we make it

    easier to add to the output later, asonlythe text file needsto be

    modified.)

  • 7/28/2019 Newton Technology Journal: Volume 1, Number 4

    20/24

    August 1995 Newton Technology Journal

    20

    Building thisproject will produce a file with a .stream extension,

    usuallyreferred to asa stream file.

    UsingaStreamFile

    Using the three arraysin another project requiresthat the stream file

    be read in to it during the build. Thisisdone byusing the

    ReadStreamFilecompile-time function. You could add a new

    text file called Streamed Data to the project to control this, and putthe following code in it:

    call func() beginforeach symbol, value in

    ReadStreamFile(HOME & MyData.stream) doDefConst(symbol, value);

    end with ();

    Now the data from the streamed project isavailable in three

    constantsfor use in the rest of the project. Building a project using a

    stream file will be much faster than constructing the arrayseach time

    the project isbuilt. You just have to remember to build a new stream file

    when the data changes.

    (Tip: During development i t maybe even faster to put the database

    in a separate package and make the three arraysavailable via a global

    variable. Doing thisallowsyou to avoid the time needed to download

    the database each time the application changes. See the Application

    Design section of the Q&Asfor detailson thisapproach.)

    (Tip: It maybe worthwhile to adopt a convention where the top-

    level object in the stream file definesanInstall function, which

    would contain code like the above Streamed Data code. Then the line to

    read in the stream file and create the constantsissimply

    ReadStreamFile(HOME & MyData.stream):Install())

    CombiningObjects

    Itspossible to save space in most packagesbycombining objects

    that are identical. For example, if the stringNew appearsin a text

    slot for two different buttons, both slotscould reference the same

    string. The behavior of the program would be virtuallyunchanged.

    In previousversion of NTK, the onlywayto accomplish thiskind of

    object sharing wasto create a compile-time constant or global variable

    to ho