From ralph Sun Jan 1 05:33:30 1989 Date: Sun, 1 Jan 89 05:33:30 MST From: "Ralph Griswold" Message-Id: <8901011233.AA09482@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA09482; Sun, 1 Jan 89 05:33:30 MST To: icon-group Subject: Happy New Year! Best wishes for the new year from the Icon Project! Ralph Griswold / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From spqr@computer-science.southampton.ac.uk Wed Jan 4 02:25:11 1989 Received: from rvax.ccit.arizona.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA13911; Wed, 4 Jan 89 02:25:11 MST Received: from UKACRL.BITNET by rvax.ccit.arizona.edu; Wed, 4 Jan 89 02:17 MST Received: from RL.IB by UKACRL.BITNET (Mailer X1.25) with BSMTP id 7299; Wed, 04 Jan 89 09:08:36 GMT Received: from caxton.cm.soton.ac.uk by hilliard.ecs.soton.ac.uk; Wed, 4 Jan 89 09:03:55 GM Date: Wed, 4 Jan 89 09:03:43 GMT From: Sebastian Rahtz Subject: returning a procedure from a procedure To: icon-group@arizona.edu Via: UK.AC.SOTON.ECS; 4 JAN 89 9:08:33 GMT Message-Id: <15891.8901040903@caxton.cm.soton.ac.uk> having just sat happily through a workshop on the Scheme dialect of Lisp, run by a colleague here, my brain started to mull over how I could persuade the colleague that Icon was even better than Scheme.... But he threw me with Lisp ability for a function to return a function as its result. Can anyone suggest to me EITHER how I pretend this isn't a good thing, OR how Icon would be persuaded to think likewise? I once wrote a SNOLBOL program which read in data mixed with patterns, and turned those patterns into valid code to apply to the associated data. It sounds like a not dissimilar problem. Any ideas? Sebastian Rahtz Computer Science University Southampton From lti!lti.com!talmage Wed Jan 4 10:05:37 1989 Received: from BU-IT.BU.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA01265; Wed, 4 Jan 89 10:05:37 MST Received: from BUITA.BU.EDU by bu-it.BU.EDU (5.58/4.7) id AA23315; Wed, 4 Jan 89 11:15:05 EST Received: by buita.bu.edu (3.2/4.7) id AA03345; Wed, 4 Jan 89 11:15:42 EST Received: from waltham.lti.com by lti.com (4.0/SMI-4.0) id AA03283; Wed, 4 Jan 89 09:45:05 EST Date: Wed, 4 Jan 89 09:45:05 EST From: talmage@lti.com (David Talmage) Message-Id: <8901041445.AA03283@lti.com> Received: by waltham.lti.com (4.0/SMI-4.0) id AA01754; Wed, 4 Jan 89 09:44:58 EST To: spqr@computer-science.southampton.ac.uk Cc: icon-group@arizona.edu In-Reply-To: Sebastian Rahtz's message of Wed, 4 Jan 89 09:03:43 GMT <15891.8901040903@caxton.cm.soton.ac.uk> Subject: returning a procedure from a procedure In <15891.8901040903@caxton.cm.soton.ac.uk>, Sebastian Rahtz writes: >But he threw me with Lisp ability for a function to return a function >as its result. Can anyone suggest to me EITHER how I pretend this >isn't a good thing, OR how Icon would be persuaded to think likewise? Couldn't you make your functions return strings which name other functions? Then you could use the Icon "call by string value" feature to call the result of the first function. It might look like this: procedure main() local result # # Tell me what to do next based on the argument to the procedure choose # result = choose( "the other thing" ) # # Use the value of result as the name of a procedure. # result() end # main procedure choose( x ) # # Returns the name of a procedure based on the value of x. # if x == "this" return "foo" if x == "that" return "bar" return "baz" end # choose procedure foo() write( "Hi! I'm foo." ) end #foo procedure bar() write( "Hello, my name is bar. What's yours?" ) end # bar procedure baz() write( "Baz is my name and sax is my axe." ) end # baz Regards, David ------------------------------------------------------------------------------ David W. Talmage ...!{buita,bbn}!lti!talmage Language Technology, Inc. talmage%lti.uucp@bu-it.bu.edu 27 Congress St., Salem, MA 01970 (508) 741-1507 From naucse!sbw Wed Jan 4 11:33:50 1989 Received: by megaron.arizona.edu (5.59-1.7/15) id AA05603; Wed, 4 Jan 89 11:33:50 MST Date: Wed, 4 Jan 89 11:24:56 mst From: naucse!sbw (Steve Wampler) Message-Id: <8901041824.AA00834@naucse> X-Mailer: Mail User's Shell (6.3 6/25/88) To: arizona!icon-group Subject: Returning functions... You must mean to return a function that is created on the fly? Otherwise, there's no problem. E.g. procedure nextfunc() suspend foo | nextfunc | write | read | stop end procedure foo() end returns the procedures 'foo' and 'nextfunc', then the functions 'write', 'read', and 'stop'. The names of functions and procedures are just global variables that have been 'initialized' to contain the function and procedure definitions. The functions and procedures themselves are just data values, and can be treated as such (with only a few operators defined on them). I think what the original poster wanted was related to SNOBOL4's CODE function - the ability to construct procedures at runtime. It would take a new operation (say a conversion from string to function) which is difficult to implement primarily because it requires the icon translator to be available at run time. In SNOBOL4 or LISP, this isn't so bad because the translators for those languages are fairly simple. For Icon, it's huge. -- Steve Wampler {....!arizona!naucse!sbw} From @x-sphinx.uchicago.edu:goer@sophist.uchicago.edu Wed Jan 4 11:47:06 1989 Received: from x-sphinx.uchicago.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA06046; Wed, 4 Jan 89 11:47:06 MST Received: from sophist.uchicago.edu by x-sphinx.uchicago.edu (5.52/2.0Sx) id AA06969; Wed, 4 Jan 89 12:51:03 CST Return-Path: Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA13716; Wed, 4 Jan 89 12:39:26 CST Date: Wed, 4 Jan 89 12:39:26 CST From: Richard Goerwitz Message-Id: <8901041839.AA13716@sophist.uchicago.edu> To: icon-group@arizona.edu Subject: returning a procedure Icon has no trouble with procedures returning procedures. You don't have to get fancy with the call by string function. It's very straightforward. (I made the same mistake some months ago, using the call by string function where it is completely unneces- sary.) The following collection of procedures, when "compiled" and run via the interpreter, will repeatedly write either FOO, BAR, or BAZ, depending on tty input. procedure main() choose(!&input)() # choose(x) returns a procedure; # choose(x)() returns a procedure, then invokes it end procedure choose(x) case x of { "this" : return foo "that" : return bar "" : fail default : return baz } end procedure foo() write("FOO") end procedure bar() write("BAR") end procedure baz() write("BAZ") end From shafto@eos.arc.nasa.gov Wed Jan 4 14:08:25 1989 Received: from eos.arc.nasa.gov by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA12169; Wed, 4 Jan 89 14:08:25 MST Received: Wed, 4 Jan 89 13:07:31 PST by eos.arc.nasa.gov (5.59/1.2) Date: Wed, 4 Jan 89 13:07:31 PST From: Michael Shafto Message-Id: <8901042107.AA22079@eos.arc.nasa.gov> To: icon-group@arizona.edu, sbw%naucse.UUCP@arizona.edu Subject: Re: Returning functions... Cc: shafto@EOS.ARC.NASA.GOV In response to the observation that maintaining the Icon translator in memory at run-time is not feasible due to the size of the translator: Understood. Hypothetically, suppose the size problem disappeared. Is there anything about the Icon language or its implementation that would preclude having a run-time "build, compile, & execute" capability like SNOBOL4's CODE()? Or, say, "EVAL()" for bounded expressions? Mike From wgg@june.cs.washington.edu Wed Jan 4 15:37:52 1989 Received: from june.cs.washington.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA15561; Wed, 4 Jan 89 15:37:52 MST Received: by june.cs.washington.edu (5.59/6.13+) id AA14237; Wed, 4 Jan 89 14:36:47 PST Date: Wed, 4 Jan 89 14:36:47 PST From: wgg@june.cs.washington.edu (William Griswold) Return-Path: Message-Id: <8901042236.AA14237@june.cs.washington.edu> To: icon-group@arizona.edu Subject: Re: returning a procedure from a procedure >From: Sebastian Rahtz >Subject: returning a procedure from a procedure >having just sat happily through a workshop on the Scheme dialect of >Lisp, run by a colleague here, my brain started to mull over how I >could persuade the colleague that Icon was even better than Scheme.... >But he threw me with Lisp ability for a function to return a function >as its result. Can anyone suggest to me EITHER how I pretend this >isn't a good thing, OR how Icon would be persuaded to think likewise? In Icon it is possible to achieve an effect *similar* to dynamically created procedures returned from procedures by using coexpressions. The idea is to return a coexpression rather than a procedure. Clearly, you do not have the flexibility of creating an arbitrary coexpression. But when a coexpression is created, the values of the variables local to the containing procedure are copied into the state of the coexpression, giving some flexibility through parameterization. However, you still only have a coexpression, not a procedure, but it is something. Now consider the example below, which is followed by its output. The result is slightly less than satisfactory (I have troubles understanding it sometimes): procedure main() every i := 1 to 5 do { plusi := plusNexp(i) every j := 1 to 5 do write("(is ",j @ plusi,", check ",i+j,")") } end # Create a coexpression that adds N to the input number procedure plusNexp(N) local cexp, T # N and T are copied into coexpression cexp := create repeat { T := N+T @ &source } @cexp # dummy call to get things going return cexp end (is 2, check 2) (is 3, check 3) (is 4, check 4) (is 5, check 5) (is 6, check 6) (is 3, check 3) (is 4, check 4) (is 5, check 5) (is 6, check 6) (is 7, check 7) (is 4, check 4) (is 5, check 5) (is 6, check 6) (is 7, check 7) (is 8, check 8) (is 5, check 5) (is 6, check 6) (is 7, check 7) (is 8, check 8) (is 9, check 9) (is 6, check 6) (is 7, check 7) (is 8, check 8) (is 9, check 9) (is 10, check 10) In Scheme when a local variable is bound into a lambda expression (runtime-created function) the value of the variable is not copied into the new function, but rather the lambda function points to the local variable on the stack. This requires the state of the parent function to persist after return. One of the major results in Scheme was finding efficient ways to provide this feature. Shared locals can be *simulated* in Icon by using static (or global) variables, rather than locals, since the former are not copied. This permits two coexpressions to share (and update!) a static variable outside the scope of the function that declares the static. The example below shows how this works: procedure main() sum1 := texp("first"); sum2 := texp("second") every i := 1 to 3 do { i @ sum1 i @ sum2 } end # shows that Z is shared procedure texp(N) local cexp # Z is copied into coexpression static Z initial Z := 1 cexp := create repeat { write("exp ",N," ",Z +:= Z @ &source) } @cexp # dummy call to get things going return cexp end exp first 2 exp second 3 exp first 5 exp second 7 exp first 10 exp second 13 The limitations and drawbacks of these mechanisms are obvious, but still have some usefulness. Bill Griswold From wgg@june.cs.washington.edu Wed Jan 4 15:58:16 1989 Received: from june.cs.washington.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA16320; Wed, 4 Jan 89 15:58:16 MST Received: by june.cs.washington.edu (5.59/6.13+) id AA16121; Wed, 4 Jan 89 14:57:13 PST Date: Wed, 4 Jan 89 14:57:13 PST From: wgg@june.cs.washington.edu (William Griswold) Return-Path: Message-Id: <8901042257.AA16121@june.cs.washington.edu> To: icon-group@arizona.edu Subject: Re: Returning functions... >From: Michael Shafto >Subject: Re: Returning functions... >In response to the observation that maintaining the Icon translator >in memory at run-time is not feasible due to the size of the translator: >Understood. Hypothetically, suppose the size problem disappeared. >Is there anything about the Icon language or its implementation that >would preclude having a run-time "build, compile, & execute" capability >like SNOBOL4's CODE()? Or, say, "EVAL()" for bounded expressions? >Mike I have implemented a dynamic linker (based on one by Bill Mitchell) for Icon that is capable of loading procedures during execution. To make linking easier, record field lookup is a bit slower. Also, it is very difficult to return unreachable procedures to free-store (I don't do it, though with a lot of work it might be possible to implement it). This doesn't address compiling during runtime, though it is certainly possible using the system() or write(...,"p") functions, good performance aside. I don't see any fundamental problem in combining the translator and interpreter, if ignoring space limitations. I think implementing a function like EVAL() might have peculiar properties in Icon, because Icon is statically rather than dynamically scoped. This would imply that the string passed to eval would be evaluated in the static context of EVAL(), rather than the procedure calling EVAL. I don't see any obvious way around this. There has been some talk of more exotic control features in Icon (such as Ken Walker's c-expressions. Ken?) that could address some of the issues discussed, but little has come of it to date, as far as I know. Bill Griswold From icon-group-request Wed Jan 4 22:56:54 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA03319; Wed, 4 Jan 89 22:56:54 MST Received: by ucbvax.Berkeley.EDU (5.61/1.33) id AA01669; Wed, 4 Jan 89 16:24:55 PST Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 5 Jan 89 00:14:41 GMT From: encore!pierson%mist@husc6.harvard.edu (Dan Pierson) Organization: Encore Computer Corp Subject: Re: Returning functions... Message-Id: <4583@xenna.Encore.COM> References: <8901041824.AA00834@naucse> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu In article <8901041824.AA00834@naucse>, sbw@naucse (Steve Wampler) writes: >I think what the original poster wanted was related to SNOBOL4's >CODE function - the ability to construct procedures at runtime. >It would take a new operation (say a conversion from string to >function) which is difficult to implement primarily because it >requires the icon translator to be available at run time. In >SNOBOL4 or LISP, this isn't so bad because the translators for >those languages are fairly simple. For Icon, it's huge. Returning new functions from functions doesn't have to involve runtime translation. Try writing the Lisp function in following in Icon: (defun account (balance) (flet ((deposit (n) (incf balance n) balance) (withdraw (n) (if (<= n balance) (progn (decf balance n) balance) (error "Tried to withdraw more money than in account"))) (balance () balance)) #'(lambda (action &optional (n 0)) (case action (deposit (deposit n)) (withdraw (withdraw n)) (balance (balance)))))) For the non-Lispers in the group, a call of account returns an anonymous function that is a closure over the argument to account. Each call to account returns a different such function, each with it's own balance "cell". A good Lisp compiler can compile all the code in the function and just compose that compiled code with a different closure at call time. In hopes of forestalling may other examples, Lisp is far from being the only language that can do this. The purpose of this example is to explain the concept, not start an "examples war" unrelated to Icon. -- dan In real life: Dan Pierson, Encore Computer Corporation, Research UUCP: {talcott,linus,necis,decvax}!encore!pierson Internet: pierson@multimax.encore.com From kwalker Thu Jan 5 11:06:28 1989 Date: Thu, 5 Jan 89 11:06:28 MST From: "Kenneth Walker" Message-Id: <8901051806.AA24260@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA24260; Thu, 5 Jan 89 11:06:28 MST In-Reply-To: <8901042257.AA16121@june.cs.washington.edu> To: icon-group Subject: Re: Returning functions... > Date: Wed, 4 Jan 89 14:57:13 PST > From: wgg@june.cs.washington.edu (William Griswold) [deleted text] > I think implementing a function like EVAL() might have peculiar properties > in Icon, because Icon is statically rather than dynamically scoped. This > would imply that the string passed to eval would be evaluated in the > static context of EVAL(), rather than the procedure calling EVAL. I > don't see any obvious way around this. EVAL() should be able to get to the environment of it's caller, along with it's caller's "procedure block". The names of local variables are stored in the procedure block, so I don't see any problem with EVAL() evaluating a string in the caller's context. The remaining issue is what to do if the string contains identifiers which do not exist in the context. Should this be an implicit declaration of the variable? Where does the variable get allocated? What is its lifetime? > There has been some talk of more exotic control features in Icon (such > as Ken Walker's c-expressions. Ken?) that could address some of the > issues discussed, but little has come of it to date, as far as I know. C-expressions are a variation on co-expressions, making them more like Lisp closures. They differ from co-expressions in three ways. 1) They share locals with the procedure that created them, along with other co-expressions created by that procedure (technically, they share locals with a particular invocation of the procedure). It is this sharing rather than copying that really makes them like Lisp closures. 2) They can be invoked using ! to generate all the results of the expression, starting from the beginning. This differs from @ which produces one result at time, remembering between activation where it left off. (Note that unary @ is still supported.) Thus ! is like a parameterless procedure invocation. 3) Value transmission (binary @) is not supported, though it can probably be done. C-expressions, when used with !, are like pararmeterless Lisp closures with no local variables. However, as a feature of Icon, they have the ability to generate results, something a Lisp closure cannot do. There are presently no plans for including them in a destributed version of Icon. Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621 2858 kwalker@Arizona.EDU {uunet|allegra|noao}!arizona!kwalker From naucse!sbw Thu Jan 5 12:37:49 1989 Received: by megaron.arizona.edu (5.59-1.7/15) id AA28092; Thu, 5 Jan 89 12:37:49 MST Date: Thu, 5 Jan 89 11:20:33 mst From: naucse!sbw (Steve Wampler) Message-Id: <8901051820.AA11572@naucse> X-Mailer: Mail User's Shell (6.3 6/25/88) To: arizona!icon-group Subject: Re: functions that return functions... On Jan 5 at 0:14, Dan Pierson writes: > >In article <8901041824.AA00834@naucse>, sbw@naucse (Steve Wampler) writes: >>I think what the original poster wanted was related to SNOBOL4's >>CODE function - the ability to construct procedures at runtime. >>It would take a new operation (say a conversion from string to >>function) which is difficult to implement primarily because it >>requires the icon translator to be available at run time. In >>SNOBOL4 or LISP, this isn't so bad because the translators for >>those languages are fairly simple. For Icon, it's huge. > >Returning new functions from functions doesn't have to involve >runtime translation. I have to disagree that this returns a 'new function', just new instances of an existing function, with different data bindings in each instance. It is quite useful, however. It can be done in Icon using co-expressions, though it is easy to create (sorry) examples that don't work this way. See the end of this note. What I was refering to was the ability to read a string in as input and evaluate it - thus the code for the function is non-existent at run time and you MUST have a translator around. >.................... Try writing the Lisp function in following in >Icon: > >(defun account (balance) > (flet ((deposit (n) > (incf balance n) > balance) > (withdraw (n) > (if (<= n balance) > (progn > (decf balance n) > balance) > (error "Tried to withdraw more money than in account"))) > (balance () > balance)) > #'(lambda (action &optional (n 0)) > (case action > (deposit (deposit n)) > (withdraw (withdraw n)) > (balance (balance)))))) > This is a nice example, I like it. It can be done in Icon as well, though not as cleanly. Here it is, slightly simplified through the use of overdraft protection: procedure new_account(bal) # most of the oddness here is to pass information # back and forth to the co-expression accnt := create |(bal := process_account(bal, bal @ &source)) @accnt # to get the co-expression rolling return accnt end procedure process_account(cur_bal,action_list) # a list is needed because we can only pass one thing # to a co-expression return case action_list[1] of { "balance" : cur_bal "deposit" : cur_bal + action_list[2] "withdrawal" : cur_bal - action_list[2] } end Can you (in LISP) return a list of three functions (specifically the three actions in the above function) that share the common balance? - this is what is missing in Icon at the current time, though there have been some schemes discussed for getting around this. This is easy in OO languages, but I was wondering if LISP had that ability (just curious). -- Steve Wampler {....!arizona!naucse!sbw} From jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK Thu Jan 5 12:37:50 1989 Received: from NSS.CS.UCL.AC.UK by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA28096; Thu, 5 Jan 89 12:37:50 MST Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP id aa06958; 5 Jan 89 19:32 GMT Date: Thu, 5 Jan 89 19:26:51 GMT Message-Id: <3933.8901051926@subnode.aiai.ed.ac.uk> From: Jeff Dalton Subject: Re: Returning functions... To: William Griswold , icon-group@arizona.edu In-Reply-To: William Griswold's message of Wed, 4 Jan 89 14:57:13 PST > I think implementing a function like EVAL() might have peculiar properties > in Icon, because Icon is statically rather than dynamically scoped. This > would imply that the string passed to eval would be evaluated in the > static context of EVAL(), rather than the procedure calling EVAL. I > don't see any obvious way around this. This problem occurs in Lisps that are lexicaly scoped. In Common Lisp, EVAL evaluates the expression in the null lexical environment. In some other Lisps, it is possible to pass an extra parameter that gives the environment to use for evaluation. Then you also need a way to create environments of the appropriate sort. Jeff Dalton, JANET: J.Dalton@uk.ac.ed AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton From wgg@june.cs.washington.edu Thu Jan 5 17:45:43 1989 Received: from june.cs.washington.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA00586; Thu, 5 Jan 89 17:45:43 MST Received: by june.cs.washington.edu (5.59/6.13+) id AA09547; Thu, 5 Jan 89 13:52:04 PST Date: Thu, 5 Jan 89 13:52:04 PST From: wgg@june.cs.washington.edu (William Griswold) Return-Path: Message-Id: <8901052152.AA09547@june.cs.washington.edu> To: icon-group@arizona.edu Subject: Re: Returning functions... >From: "Kenneth Walker" >Subject: Re: Returning functions... [regarding implementing EVAL() in Icon] >EVAL() should be able to get to the environment of it's caller, along >with it's caller's "procedure block". The names of local variables are >stored in the procedure block, so I don't see any problem with EVAL() >evaluating a string in the caller's context. The remaining issue is >what to do if the string contains identifiers which do not exist >in the context. Should this be an implicit declaration of the >variable? Where does the variable get allocated? What is its lifetime? I have no doubts about its implementation, but it would create a second kind of scoping in Icon. Once you have made it available to EVAL(), what about other cool functions that could use dynamic scoping (or whatever it would turn out to be)? It wouldn't be ``fair'' (or regular) to give it only to EVAL(), but having two scoping mechanisms in Icon could considerably complicate the implementation of Icon. Also, it would make Icon programs harder to understand, since you could never be sure what scoping mechanism is used (unless of course you found a way to syntactically differentiate the *use* of dynamic and static variables, and that would be a mess). This is what I meant by no obvious (easy) way out. Bill Griswold From jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK Thu Jan 5 19:48:31 1989 Received: from NSS.CS.UCL.AC.UK by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA03951; Thu, 5 Jan 89 19:48:31 MST Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP id aa08632; 6 Jan 89 0:01 GMT Date: Thu, 5 Jan 89 23:56:28 GMT Message-Id: <4191.8901052356@subnode.aiai.ed.ac.uk> From: Jeff Dalton Subject: Re: functions that return functions... To: sbw , icon-group <@arizona.edu:icon-group@arizona> In-Reply-To: Steve Wampler's message of Thu, 5 Jan 89 11:20:33 mst > I have to disagree that this returns a 'new function', just new > instances of an existing function, with different data bindings > in each instance. You might also say it's a new function that happens to execute the same code as some other functions, but I don't think whether a closure is really a new function is a very interesting question. > Can you (in LISP) return a list of three functions (specifically the > three actions in the above function) that share the common balance? - Yes. -- Jeff From jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK Thu Jan 5 19:51:55 1989 Received: from NSS.CS.UCL.AC.UK by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA04016; Thu, 5 Jan 89 19:51:55 MST Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP id aa08519; 5 Jan 89 23:41 GMT Date: Thu, 5 Jan 89 23:36:24 GMT Message-Id: <4139.8901052336@subnode.aiai.ed.ac.uk> From: Jeff Dalton Subject: Re: returning a procedure from a procedure To: David Talmage , spqr%computer-science.southampton.ac.uk@NSS.Cs.Ucl.AC.UK In-Reply-To: David Talmage's message of Wed, 4 Jan 89 09:45:05 EST Cc: icon-group@arizona.edu > Couldn't you make your functions return strings which name other functions? > Then you could use the Icon "call by string value" feature to call the > result of the first function. It might look like this: Not good enough, because the number of procedure objects is fixed. In Scheme, I can do this: (define (make-counter) (let ((count 0)) (lambda () (set! count (+ count 1)) count))) The two calls to MAKE-COUNTER would return two different procedures, as in: > (define c1 (make-counter)) # > (define c2 (make-counter)) # > (c1) 1 > (c1) ;gets one bigger each time 2 > (c2) ;but this one hasn't started counting yet. 1 Jeff Dalton, JANET: J.Dalton@uk.ac.ed AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton From jeff%aiai.edinburgh.ac.uk@NSS.Cs.Ucl.AC.UK Thu Jan 5 20:17:41 1989 Received: from NSS.CS.UCL.AC.UK by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA04780; Thu, 5 Jan 89 20:17:41 MST Received: from aiai.edinburgh.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP id aa08486; 5 Jan 89 23:32 GMT Date: Thu, 5 Jan 89 23:27:36 GMT Message-Id: <4119.8901052327@subnode.aiai.ed.ac.uk> From: Jeff Dalton Subject: Re: returning a procedure from a procedure To: Sebastian Rahtz , icon-group@arizona.edu In-Reply-To: Sebastian Rahtz's message of Wed, 4 Jan 89 09:03:43 GMT > having just sat happily through a workshop on the Scheme dialect of > Lisp, run by a colleague here, my brain started to mull over how I > could persuade the colleague that Icon was even better than Scheme.... > But he threw me with Lisp ability for a function to return a function > as its result. Can anyone suggest to me EITHER how I pretend this > isn't a good thing, OR how Icon would be persuaded to think likewise? > > I once wrote a SNOLBOL program which read in data mixed with patterns, > and turned those patterns into valid code to apply to the associated > data. It sounds like a not dissimilar problem. There are two Lispish capabilities that might be confused. One is tha ability to turn some list-structure data into code or to treat it as code, the other is the ability to return procedural values. For example, (define (compose f g) (lambda (x) (f (g x)))) COMPOSE is a function that returns the composition of two other functions. Jeff Dalton, JANET: J.Dalton@uk.ac.ed AI Applications Institute, ARPA: J.Dalton%uk.ac.ed@nss.cs.ucl.ac.uk Edinburgh University. UUCP: ...!ukc!ed.ac.uk!J.Dalton From icon-group-request Fri Jan 6 21:10:09 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA09037; Fri, 6 Jan 89 21:10:09 MST Received: by ucbvax.Berkeley.EDU (5.61/1.33) id AA22601; Fri, 6 Jan 89 18:30:48 PST Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 7 Jan 89 00:01:50 GMT From: encore!pierson%mist@bu-cs.bu.edu (Dan Pierson) Organization: Encore Computer Corp Subject: Re: functions that return functions... Message-Id: <4606@xenna.Encore.COM> References: <8901051820.AA11572@naucse> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu In article <8901051820.AA11572@naucse>, sbw@naucse (Steve Wampler) writes: >Can you (in LISP) return a list of three functions (specifically the >three actions in the above function) that share the common balance? - >this is what is missing in Icon at the current time, though there have >been some schemes discussed for getting around this. This is easy in >OO languages, but I was wondering if LISP had that ability (just curious). Sure, just replace the return value of my previous example with: '(#'deposit #'withdraw #'balance) -- dan In real life: Dan Pierson, Encore Computer Corporation, Research UUCP: {talcott,linus,necis,decvax}!encore!pierson Internet: pierson@multimax.encore.com From icon-group-request Fri Jan 13 17:40:12 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA27491; Fri, 13 Jan 89 17:40:12 MST Received: by ucbvax.Berkeley.EDU (5.61/1.33) id AA13254; Fri, 13 Jan 89 16:29:54-0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 13 Jan 89 04:12:00 GMT From: uxg.cso.uiuc.edu!uicbert.eecs.uic.edu!wilson@uxc.cso.uiuc.edu Subject: Re: Returning functions... Message-Id: <93400001@uicbert.eecs.uic.edu> References: <8901041824.AA00834@naucse> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu Excuse me if *I've* misunderstood the issue, but it seems to me that somebody should separate the issues of scope and extent clearly. (Preferably, somebody who knows Icon better than me -- I'm just starting a class on it. But here goes. I'm hoping this will motivate a discussion of potential cross-fertilization between the Scheme and Icon communities. I would expect people who like either language to like the other, and I'm considering snarfing some Icon features for an extended Scheme implementation.) Some important things: 1. Scheme and Common Lisp are both lexically scoped. There is an easy way of implementing this, though it's not the most efficient. If Icon worked that way, there wouldn't be any confusion of which scoping mechanism was being used -- Icon's two-level static scoping is a degenerate case of Scheme's lexical scoping. (Note that Common Lisp and most implementations of Scheme *also* support dynamically scoped variables, but lexical scope is the default. The combination of the two is harder to implement than either one alone.) 2. What's peculiar about Scheme (and Common Lisp when you exploit lexical closures) is that variable bindings have "indefinite extent". This means that the space for the local variables of a procedure are allocated on the garbage-collected heap, not on the stack (in the general case). Scheme's scoping is essentially the same as Pascal's, and it can be implemented the same way, using static chains or displays at run time for variable lookup. That is, at run-time each executing procedure's activation record holds a pointer to an activation record of the procedure it was declared inside. In Pascal, I never cared much about scoping -- two or three levels is enough for me. But when it's combined with indefinite extent, as in Scheme, you can do a lot of interesting and useful things. If you avoid a few particlar operations in Scheme, the "environment frames" that hold the local variables for a procedure call become garbage when the procedure returns, because the activation records they belong to are popped off the stack. The only consequence of heap-allocated variables in such circumstances is that you have to wait for a garbage collection to reclaim the space, rather than the activation's space for variables off the stack too. But something funny happens if a procedure creates a new procedure at run time. The variable bindings that the currently executing procedure is using are "captured" when the new procedure is created. Whenever the new procedure is executed, that binding environment will be restored for it to execute in. So if there's as long as there's a possibility of executing a procedure that was created in a particular binding environment, that environment won't be reclaimed by the gc. Let me make that a little more concrete. If you use a static chain, the links in the static chain reflect the nesting of he procedures in the source code. Suppose procedure B s nested inside procedure A in the source code ("lexically"). When procedure B is called, an environment frame is created to hold its local variables for that call. This environment frame has a scoping pointer (static link) to an environment frame for an activation of A. The procedure can only see the versions of variables along that static chain. The "capture" of a binding environment is then just the saving of a pointer to the currently executing procedure's environment frame. The garbage collector won't reclaim the space for any of the frames along the chain because each keeps a pointer to the next one. To restore the environment for a procedure to execute in, the system just puts the pointer to that environment back in the "current environment" register. (Or does something equivalent with a display.) So whenever a new procedure is created by a running program, a "lexical closure" is created. This is just an object that holds two things: the code to execute, and a pointer to the environment to execute it in (the current environment when the object is created). So if you save the closure (by storing it in a global variable, say), you're implicitly saving all of the variable bindings that were in effect when it was created. But if you don't save any new procedures, you can treat Scheme just like Pascal. -------------------------------------------------------------------------- I needed to write this out for some undergrads I'm teaching anyway, so here's an example: So suppose we're in the top-level loop in Scheme, just typing things to the interpreter and having it interpret them. If we type (let ((x 0)) (some-procedure x)) what we're doing is creating a new environment frame and executing a procedure in it. "let" creates a frame that has space for one variable, "x", whose initial value will be zero. That environment will be an extension to whatever environment had been in effect. It then executes the rest of the expressions in that environment. When it's done, it restores the old environment. If we're starting out in the usual user-interaction mode, the "current environment" is just the global variable bindings. While we're inside the body of the let, variable lookups will look in the new frame it creates (holding a binding for x) before looking in the globals. A slightly more interesting example is to execute a procedure, inside the "let" that creates a new procedure object. (let ((x 0)) (make-procedure () (set! x (+ x 1)) (return x))) (This isn't quite real Scheme, but it's clearer to non-lispers.) What happens here is that the new environment is created and then a new procedure is constructed. When executed, that procedure will restore the environment created by the let and add 1 to the value of x in that environment. It will then return the value of x from that environment to whoever called it. Since that version of x exists between calls (as long as the procedure exists), it keeps its state between calls, and the procedure acts as a counter. Every time you call it, it computes the next number and gives it back to you. But how do we get ahold of the procedure, to keep it around so that we can call it? We can take advantage of the fact that "let" returns the value of the last statement that it executes. In this case, that's just the call to make-procedure. We can save the procedure object by making it the value of a global variable, say, "count". (set! count (let ((x 0)) (make-procedure () (set! x (+ x 1)) (return x)))) So now we can call the procedure, which is the value of variable "count", the way we call any procedure in Scheme: (count) will do it. Finally, we can easily generalize this to make a procedure that will create a new counter procedure every time we call it. We'll store this procedure in the variable "create-counter". (set! create-counter (make-procedure () (let ((x 0)) (make-procedure () (set! x (+ x 1)) (return x))))) Every time we execute the procedure stored in make-counter, it will create a new binding environment with its own version of the variable x. It will then create a new procedure that increments that version of x and returns its value. In real Scheme, "make-procedure" is called "lambda", for historical reasons. And you don't have to explicitly return a value -- most procedures automatically return their last subexpression's value by default. Setq returns the value it has assigned to the variable being set. So the above procedure would really look like this: (set! create-counter (lambda () (let ((x 0)) (lambda () (set! x (+ x 1)))))) This is how Scheme's combination of lexical scoping and indefinite extent gives you the ability to package procedures and data together to get the funcionality of objects. Slightly more complicated programs can be written that compute infinite "streams" of data, one piece at a time, on demand. These can be combined into streams that are mappings of other streams, all of them potentially infinite, and each asking others only for the information it needs, as it needs it. This gives you the ability to manipulate potentially infinite lists, as long as you don't actually ever need the whole list at any given time. For example, you might create an object similar to the counter that calls a counter and then returns the square of the result, giving a consecutive squares. A slightly more general procedure may be used to combine any function with any stream, producing a stream that always maps the function onto the next element of the stream. Thus a few types of streams and a few types of functions can easily be combined to yield a large variety of streams, each yielding an infinite sequence, one element at a time. ------------------------------------------------------------------------- For a beautiful (though dense) introduction to programming in Scheme and implementing Scheme, the standard text is Abelson and Sussman's "Structure and Interpretation of Computer Programs". They show how to write basic programs in Scheme, using elegant techniques like stream combination and object-centered programming; they even show how to implement a Scheme interpreter in Scheme, and even a Scheme compiler. It's a great book -- it's easy enough to understand, although there is a temptation to try to breeze through it. The ideas are simple and powerful, but there are enough of them that you should digest them reasonably well. (That one book contains half of a good education in Computer Science, if you ask me.) Oh yeah -- another important thing about Scheme's scoping is that it can be compiled efficiently. The fact that the static chain or display corresponds to the static structure of the program means that the compiler can infer enough stuff at compile time that the code can be quite good. And there's no problem with concurrent versions of Scheme, with several threads executing in their own "current" environments. (Dynamic binding can be a real headache combined with multitasking.) -- Paul Paul R. Wilson Human-Computer Interaction Laboratory U. of Ill. at C. EECS Dept. (M/C 154) wilson@uicbert.eecs.uic.edu Box 4348 Chicago,IL 60680 From hdan@sleepy.cc.utexas.edu Sun Jan 15 00:37:43 1989 Received: from emx.utexas.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA20100; Sun, 15 Jan 89 00:37:43 MST Received: by emx.utexas.edu (5.54/5.51) id AA29961; Sun, 15 Jan 89 01:38:03 CST Date: Sun, 15 Jan 89 01:36:31 CST From: hdan@sleepy.cc.utexas.edu (Dan Higdon) Posted-Date: Sun, 15 Jan 89 01:36:31 CST Message-Id: <8901150736.AA22446@sleepy.cc.utexas.edu> Received: by sleepy.cc.utexas.edu (5.51/5.51) id AA22446; Sun, 15 Jan 89 01:36:31 CST To: icon-group@arizona.edu Subject: tools Does anyone out there know where I can find the MS-DOS or OS/2 versions of YACC/LEX/AWK? Obviously I would prefer shareware or pd over having to purchase "commercial" software. (I know this seems to have little to do with Icon, but they all fit into the programming languages topic, right?) hdan@sleepy.cc.utexas.edu .s From ralph Sun Jan 15 18:23:43 1989 Date: Sun, 15 Jan 89 18:23:43 MST From: "Ralph Griswold" Message-Id: <8901160123.AA22086@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA22086; Sun, 15 Jan 89 18:23:43 MST To: icon-group Subject: Version 7.5 of Icon for UNIX and VMS Version 7.5 of Icon is now available for UNIX and VMS systems. The changes are minor as far as the language itself is concerned. The main changes are in the implementation, which has been somewhat reorganized. If you're using an earlier Version 7 Icon and having no troubles, there is no particular reason for you to get Version 7.5 (although we no longer support earlier versions). If you're still using Version 6, you should seriously consider upgrading to Version 7.5. Version 7.5 for UNIX and VMS is available via FTP. Do an anonymous FTP to arizona.edu; cd to icon; and get README, which lists what's available. If you do not have access to FTP, Version 7.5 Icon for UNIX and VMS can be obtained on magnetic tape for $25 each, which includes shipping in the United States and Canada, as well as hardcopy documentation. Order tapes from Icon Project Department of Computer Science Gould-Simpson Building The University of Arizona Tucson, AZ 85721 USA There is a $10 shipping charge per tape for orders sent outside the United States and Canada. Payment must be in US dollars. Checks must be drawn on a bank with a branch in the United States. Postal Money orders in US dollars also are acceptable. Please address any questions to me (not to icon-group). Ralph E. Griswold Department of Computer Science Gould-Simpson Building University of Arizona Tucson, AZ 85721 USA ralph@Arizona.EDU uunet!arizona!ralph From dscargo@cim-vax.honeywell.com Mon Jan 16 07:44:39 1989 Message-Id: <8901161444.AA15247@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA15247; Mon, 16 Jan 89 07:44:39 MST Date: 16 Jan 89 08:24:00 CST From: "DAVE CARGO" Subject: changes from v7 to v7.5 To: "icon-group" If you aren't going to summarize the changes between v7 and v7.5, can you at least point to a file for FTP that discusses the differences? Most importantly, is the new version completely upward compatible? dsc From dscargo@cim-vax.honeywell.com Mon Jan 16 08:05:33 1989 Message-Id: <8901161505.AA16153@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA16153; Mon, 16 Jan 89 08:05:33 MST Date: 16 Jan 89 08:52:00 CST From: "DAVE CARGO" Subject: Areas for possible enhancement To: "icon-group" While writing what is a fairly simple program in Icon, I discovered some aspects of the language that could be changed to make certain programs even easier to write. Of the built-in character sets, there isn't one that's just the printable characters. There are the upper- and lower-case letters, and more recently the digits, but there's also all the punctuation. I realize that a global variable and an initialization could solve the lack, but I was wondering if this lack might be a common problem. Is there a simple way to do radix conversion from the user level? Sometimes I've wanted to translate a byte from 8-bit integer to hexadecimal representation. There appears to be something internal used for conversion to octal (used for image of control charcters), but again it doesn't seem to be user accessible. Decimal, hex, octal, and maybe binary would be the set of radices most likely to be used, I expect. I also found myself wondering if there was a way to discover from a running program how close to the limits of memory capacity I'd come, some way to measure the "high water marks" in the various structures that are of fixed size. Of hand I don't know how many of them there are, but it would be nice to know actual maximum and max available for whatever there are. Actually, I shouldn't call these "language changes". They are more like additions to built-ins. I was wondering what the fastest (and clearest) method of testing for the the membership of a character in a cset. Has member been generalized to work on csets as well as sets and tables? I was noticing in the one page Icon reference sheet that came in the latest newsletter that the built-in function "collect()" was listed. I didn't recognize it. What does it do? Also, there seems to be enough space that some of the syntax for the data types could be added. While using the quotation marks for strings and apostrophes for csets would be useful only to the rankest beginners, specifying the radix of integers is a syntactical element used infrequently enough that noting it on the sheet seems reasonable. Some of the type constructors (like list and set) would also be useful for beginners. I'm sorry if I'm sounding picky, but by-and-large the work done with Icon seems to be so good and useful that only some of the little things are left to discuss. One more thing just occurred to me. For people trying to manage their own program's runtime resources, would a "size" or "memsize" function that lets them measure the actual memory size of variables be hard to do? Sizing of things is not something that's discussed much at the language level. Appreciatively yours, David S. Cargo From ralph Mon Jan 16 16:26:03 1989 Date: Mon, 16 Jan 89 16:26:03 MST From: "Ralph Griswold" Message-Id: <8901162326.AA07224@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA07224; Mon, 16 Jan 89 16:26:03 MST To: icon-group Subject: Icon Version 7.5 vs 7.0 A few persons have asked for the details of the minor language changes between Version 7.5 and 7.0 of Icon. Here's the information: ======================================================================= Command-Line Options: Options to icont must precede file names on the command line. For example, icont -o manager proto.icn not icont proto.icn -o manager The position of options has always been documented this way, but it was not enforced previously. Consequently, options in the incorrect position that worked before will not work now. This problem is most likely to occur in scripts that were composed under earlier version of Icon. Note that the -x option is an exception; it must occur after all file names for icont, since any command-line arguments after -x apply to execution (iconx). Co-Expressions: The initial size of &main is now 1, instead of 0, to reflect its activation to start program execution. An attempt to refresh &main results in a run-time error. (Formerly, it caused a memory violation.) Change in Function to Force Garbage Collection: Garbage collection is forced by the function collect(i,j). The value of i specifies the region and the value of j specifies the amount of space that must be free following the collection. The regions are designated as follows: i region 1 static 2 string 3 block The region specified is reflected in the values generated by &collections. A value of 0 for i causes a garbage collection without a specific region. In this case, the value of j is irrelevant. The default values for i and j are 0. Miscellaneous: ``Unprintable'' characters in strings now are imaged with hex- adecimal escape sequences rather than with octal ones. The function display(f,i) now prints the image of the current co-expression before listing the values of variables. If the value of &trace is negative, it is decremented every time a trace message is written. Previously it was left unchanged. This change does not affect tracing itself, but it does allow the number of trace messages that have been written to be determined by a running program. The environment variable BLOCKSIZE is now a synonym for HEAP- SIZE. ======================================================================= A printable copy of a technical report describing Version 7.5 of Icon is in the FTP area as decsribed earlier. Get version7.doc. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From kwalker Wed Jan 18 17:25:17 1989 Date: Wed, 18 Jan 89 17:25:17 MST From: "Kenneth Walker" Message-Id: <8901190025.AA14525@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA14525; Wed, 18 Jan 89 17:25:17 MST In-Reply-To: <8901161505.AA16153@megaron.arizona.edu> To: icon-group Subject: Re: Areas for possible enhancement > Date: 16 Jan 89 08:52:00 CST > From: "DAVE CARGO" > Of the built-in character sets, there isn't one that's just the printable > characters. There are the upper- and lower-case letters, and more recently > the digits, but there's also all the punctuation. I realize that a global > variable and an initialization could solve the lack, but I was wondering if > this lack might be a common problem. Is there a subset of the ASCII character set which is "officially" printable? If not, then it will be difficult to decide what &printable should contain. Even if such a subset does exist, the Icon Project is trying to support EBCDIC for the IBM mainframe world; can &printable be the same for both character sets? &digits was added because it is very commonly needed. I suspect there are other csets which are commonly used, but, as you point out, they are easy to construct with a global variable and an initialization. > Is there a simple way to do radix conversion from the user level? Sometimes > I've wanted to translate a byte from 8-bit integer to hexadecimal > representation. There appears to be something internal used for conversion > to octal (used for image of control charcters), but again it doesn't seem to > be user accessible. Decimal, hex, octal, and maybe binary would be the > set of radices most likely to be used, I expect. I beleive there are radix conversion routines in the Icon program library, though I haven't looked at them. Have you looked at the new built-in functions for bit manipulation and the ones for converting between characters and integers? > I also found myself wondering if there was a way to discover from a running > program how close to the limits of memory capacity I'd come, some way to > measure the "high water marks" in the various structures that are of fixed > size. Of hand I don't know how many of them there are, but it would be > nice to know actual maximum and max available for whatever there are. Icon storage is divided into 3 regions: static, string, and block. Most data except strings and co-expressions are allocated in the block region. The current size of these regions can be found using the new keyword ®ions: every write(®ions) This prints the 3 sizes in the order given above. If you are using a "fixed regions" version of Icon, the size of the static region is meaningless (the run-time system does a C malloc() to get storage for co-expressions). If you are running an "expandable regions" version of Icon these regions may grow in size, so this doesn't really tell you how close you are to using up available storage. The keyword &storage can be used to tell home much of each region is currently being used: every write(&storage) The value for the static region is given for consistancy, but does not, in fact, tell you how much of the region has been used. To accurately find out how much storage is being used, you should force a garbage collection first to compact the string and block regions: collect() every write(&storage) > I was wondering what the fastest (and clearest) method of testing for the > the membership of a character in a cset. Has member been generalized to work > on csets as well as sets and tables? A difficulty with extending member() is that Icon has no character data type, which is, of course, what a member of a cset is. The best thing you can do is cset intersection and see if the result is the empty cset: if (c ** 'a') == '' then ... > I was noticing in the one page Icon reference sheet that came in the latest > newsletter that the built-in function "collect()" was listed. I didn't > recognize it. What does it do? As noted above, it forces a garbage collection. > Also, there seems to be enough space that > some of the syntax for the data types could be added. While using the > quotation marks for strings and apostrophes for csets would be useful only > to the rankest beginners, specifying the radix of integers is a syntactical > element used infrequently enough that noting it on the sheet seems reasonable. > Some of the type constructors (like list and set) would also be useful for > beginners. Those sound to me like reasonable additions to consider. > One more thing just occurred to me. For people trying to manage their own > program's runtime resources, would a "size" or "memsize" function that lets > them measure the actual memory size of variables be hard to do? Sizing of > things is not something that's discussed much at the language level. It shouldn't be too difficult, you just need to be familar with how all the data types are implemented so you can compute their sizes (of course, that doesn't insure that someone here will actually to do it). Are you thinking of a function which only looks at the first level of a structure (just as copy only copies the first level) or do you want something which follows sub-structures to the end. The problem, of course, is that structures can be circular, so detecting the "end" requires some extra book keeping. Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621 2858 kwalker@Arizona.EDU {uunet|allegra|noao}!arizona!kwalker From icon-group-request Wed Jan 18 19:09:13 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA18897; Wed, 18 Jan 89 19:09:13 MST Received: by ucbvax.Berkeley.EDU (5.61/1.33) id AA28643; Wed, 18 Jan 89 17:39:02-0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 18 Jan 89 06:12:00 GMT From: uxg.cso.uiuc.edu!uicbert.eecs.uic.edu!wilson@uxc.cso.uiuc.edu Subject: data backtracking, more general con Message-Id: <93400002@uicbert.eecs.uic.edu> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu Is anyone working on an Icon-like language with more orthogonal control structures and data types? Is anyone working on a more general expression evaluation mechanism? I've figured out how to accomplish general data backtracking in a garbage collected heap, and in fact how to extend it to "sidetracking." (More than one subexpression may execute simultaneously, with each isolated from the others' side effects. The parent expression can choose to keep the side effects of at most one of the subexpressions.) This can be done with a certain amount of continual overhead on stock hardware, and probably with negligible overhead on Lisp machines. What I'm mostly looking for is ideas of what a language with such powerful facilities should look like. Icon strikes me as a sort of hodgepodge of features and types, but the particular combinations of features and types seem to work remarkably well together. You use backtracking where appropriate, and assemble the rest as an imperative program. Icon's simple backtracking mechanism may be as complex a predefined evaluation mechanism as you'd want, since a more general mechanism wouldn't give you enough familiar idioms to be able to make sense of a program. On the other hand, a multiway mechanism seems very valuable if it is truly parallel, so a certain extra complexity is doubtless worthwhile. How much of Icon's inconsistency is the source of its simple power? How much does backtracking serve to foster abstractions of the operation of a system. (The way an interpreter can usually be considered a central DFA that gives its abstract state, but with the actual program data *not* being like a DFA -- it's the concrete state that the DFA leverages off of to do real work.) What would you want control constructs to look like, if you could have anything you wanted? This question has two sides -- one for language prototyping, and one for language use. What should a very general evaluation mechanism be like, to enable the prototyping of things like backtracking? What set of fixed or default mechanisms would you want if you could only pick a couple of simple ones to actually use in programs all the time? I've thought of several ways my side-effect isolation system could be useful (especially for concurrency), but I'm looking for more. Any suggestions are welcome. Pointers to related work would be very helpful. (I'm a somewhat familiar with multiple-context reasoning in AI systems already, but only in the most general way.) Thanks prematurely, Paul Paul R. Wilson Human-Computer Interaction Laboratory lab ph.: (312) 413-0042 U. of Ill. at Chi. EECS Dept. (M/C 154) wilson@uicbert.eecs.uic.edu Box 4348 Chicago,IL 60680 (or wilson@carcoar.stanford.edu) From icon-group-request Thu Jan 19 01:20:57 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA00391; Thu, 19 Jan 89 01:20:57 MST Received: by ucbvax.Berkeley.EDU (5.61/1.33) id AA05768; Thu, 19 Jan 89 00:09:14-0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 19 Jan 89 04:31:40 GMT From: cjeffery@arizona.edu (Clinton Jeffery) Organization: U of Arizona CS Dept, Tucson Subject: Re: Areas for possible enhancement Message-Id: <8768@megaron.arizona.edu> References: <8901190025.AA14525@megaron.arizona.edu> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu From "Kenneth Walker" >> From: "DAVE CARGO" >> Has member been generalized to work on csets as well as sets and tables? > > A difficulty with extending member() is that Icon has no character data > type, which is, of course, what a member of a cset is. The best thing > you can do is cset intersection and see if the result is the empty cset: > if (c ** 'a') == '' then ... Oh, gross! Defining member(c1,c2) to be equivalent to ((c1 ** c2) ~=== '') would be a minor inelegance for a major improvement in clarity. It would also be trivial to implement and wouldn't break any existing programs. -- | Clint Jeffery, University of Arizona Department of Computer Science | cjeffery@arizona.edu -or- {noao allegra}!arizona!cjeffery -- From gudeman Thu Jan 19 11:12:21 1989 Date: Thu, 19 Jan 89 11:12:21 MST From: "David Gudeman" Message-Id: <8901191812.AA23609@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA23609; Thu, 19 Jan 89 11:12:21 MST To: icon-group@arizona.edu In-Reply-To: (Clinton Jeffery's message of 19 Jan 89 04:31:40 GMT <8768@megaron.arizona.edu> Subject: Areas for possible enhancement >From: cjeffery@arizona.edu (Clinton Jeffery) >>From "Kenneth Walker" >> ... The best thing you can do is cset intersection and see if the >>> result is the empty cset: >> if (c ** 'a') == '' then ... >Oh, gross! Defining member(c1,c2) to be equivalent to ((c1 ** c2) ~=== '') >would be a minor inelegance for a major improvement in clarity. It would >also be trivial to implement and wouldn't break any existing programs. Or you can just use any(c,"a") ``is "a" a member of c?'' Is that just too grody for words too Clint? From icon-group-request Thu Jan 19 16:53:01 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA12289; Thu, 19 Jan 89 16:53:01 MST Received: by ucbvax.Berkeley.EDU (5.61/1.33) id AA21378; Thu, 19 Jan 89 15:42:01-0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 19 Jan 89 21:58:10 GMT From: cjeffery@arizona.edu (Clinton Jeffery) Organization: U of Arizona CS Dept, Tucson Subject: Re: Areas for possible enhancement Message-Id: <8788@megaron.arizona.edu> References: <8901191812.AA23609@megaron.arizona.edu> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu From: gudeman@ARIZONA.EDU ("David Gudeman"): >>From: cjeffery@arizona.edu (Clinton Jeffery) >>>From "Kenneth Walker" , discussing cset membership >>> if (c ** 'a') == '' then ... >>Oh, gross! > Or you can just use any(c,"a"). > Is that just too grody for words too Clint? Naw, this is probably what I would do in the current language (slower or not; its cleaner). I guess I would like set functions to "do the right thing" with csets. -- | Clint Jeffery, University of Arizona Department of Computer Science | cjeffery@arizona.edu -or- {noao allegra}!arizona!cjeffery -- From gudeman Thu Jan 19 18:13:53 1989 Date: Thu, 19 Jan 89 18:13:53 MST From: "David Gudeman" Message-Id: <8901200113.AA15815@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA15815; Thu, 19 Jan 89 18:13:53 MST To: icon-group@arizona.edu In-Reply-To: (Clinton Jeffery's message of 19 Jan 89 21:58:10 GMT <8788@megaron.arizona.edu> Subject: Areas for possible enhancement >From: cjeffery@arizona.edu (Clinton Jeffery) >From: gudeman@ARIZONA.EDU ("David Gudeman"): >>>From: cjeffery@arizona.edu (Clinton Jeffery) >>>>From "Kenneth Walker" , discussing cset membership >>>> if (c ** 'a') == '' then ... >> Or you can just use any(c,"a"). >... this is probably what I would do in the current language >(slower or not; its cleaner). I guess I would like set functions >to "do the right thing" with csets. Actually, its hard to imagine anything faster if "a" is already a string. If you have to convert it, then Ken's way may be faster. How about this: procedure Member(S,x) if S := cset(S) then return any(S,x) & x return member(S,x) end The assignment is in case S is a string, then you only have to convert it once. You can leave that out, or avoid it by: procedure Member(S,x) return any((cset(S) | return member(S,x))\1, x) end Isn't Icon a great language? BTW, I havn't actually tried these... From ralph Fri Jan 20 07:19:47 1989 Date: Fri, 20 Jan 89 07:19:47 MST From: "Ralph Griswold" Message-Id: <8901201419.AA12268@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA12268; Fri, 20 Jan 89 07:19:47 MST To: icon-group Subject: cset membership Some of you may be wondering about the relative speed of two methods suggested for testing membership in csets. Here are the results of benchmark tests (done on a VAX 8650, but I'd not expect the processor to have much effect on the relative timings): c := &lcase . . . (c ** 'a') ~== '' # 0.154ms in loop any(c,"a") # 0.103ms in loop Of course, there are several parameters that might affect timings. The size of the cset, where 'a' is in it, etc, what happens if it isn't in the cset, and so forth. I've not attempted these variations. Worth noting is that the cset intersection method allocates 40 bytes per instance (cset intersection produces a new cset), while any() allocates no storage. Allocation, even if transient, has to be paid for eventually, assuming the program runs long enough to cause a garbage collection. Note that the examples above are chosen not to require implicit type conversions. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Sat Jan 21 10:05:41 1989 Received: from mailgw.cc.umich.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA18115; Sat, 21 Jan 89 10:05:41 MST Received: from umix.cc.umich.edu by mailgw.cc.umich.edu (5.59/1.0) id AA10157; Sat, 21 Jan 89 12:01:06 EST Received: by umix.cc.umich.edu (5.54/umix-2.0) id AA29077; Sat, 21 Jan 89 12:06:40 EST Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sat, 21 Jan 89 12:03:26 EST Date: Sat, 21 Jan 89 11:39:40 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@arizona.edu Message-Id: <112195@Wayne-MTS> Subject: File retrieval with wildcards for MS-DOS The following procedure can be useful in operating on a set of files specified by wildcards. I suspect something similar will work for Unix. Paul Abrahams ======================================================== # get_filename(pfn) accepts a DOS filename possibly containing wildcards. # The filename can also include a drive letter and path. # If the filename ends in "\" or ":", "*.*" is appended. # The result sequence is a sequence of the filenames corresponding to pfn. procedure get_filename(pfn) local asciiz, fnr, prefix, k, name local ds, dx, result, fnloc, string_block #get Disk Transfer Address; filename locn is 30 beyond that result := Int86([16r21, 16r2f00] ||| list(7,0)) fnloc := 16 * result[8] + result[3]+ 30 # get the generalized filename fnr := reverse(pfn) k := upto("\\:", fnr) | *fnr + 1 prefix := reverse(fnr[k:0]) name := "" ~== reverse(fnr[1:k]) | "*.*" # Get the first file in the sequence asciiz := prefix || name || "\x00" Poke(string_block := GetSpace(*asciiz), asciiz) ds := string_block / 16 dx := string_block % 16 result := Int86([16r21, 16r4e00, 0, 0, dx, 0, 0, 0, ds]) case result[2] of { 0 : {} 18 : fail default : stop("i/o error ", result[2]) } suspend prefix || extract_name(fnloc) # Get the remaining files in the sequence while Int86([16r21, 16r4f00, 0, 0, 0, 0, 0, 0, 0])[2] = 0 do suspend prefix || extract_name(fnloc) end procedure extract_name(fnloc) local asciiz asciiz := Peek(fnloc, 13) return asciiz[1:upto("\x00", asciiz)] end ================================================================== P.S. - In using Int86, I noticed that the first item on the returned list, which should be the contents of the flag register, seems not to be correct. It seems to be always the same as the second item (the ax register). Is there a bug here? From @x-sphinx.uchicago.edu:goer@sophist.uchicago.edu Sat Jan 21 11:32:22 1989 Received: from x-sphinx.uchicago.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA02566; Sat, 21 Jan 89 11:32:22 MST Received: from sophist.uchicago.edu by x-sphinx.uchicago.edu (5.52/2.0Sx) id AA04704; Sat, 21 Jan 89 12:31:43 CST Return-Path: Received: by sophist.uchicago.edu (3.2/UofC3.0) id AA05880; Sat, 21 Jan 89 12:24:21 CST Date: Sat, 21 Jan 89 12:24:21 CST From: Richard Goerwitz Message-Id: <8901211824.AA05880@sophist.uchicago.edu> To: icon-group@arizona.edu Subject: different strokes I was looking over Paul Abrahams' get_filename procedure, think about how differently icon programmers typically work. I, for instance would probably have written a certain section of his program like this: reverse(pfn) ? { name := reverse("" ~== tab(upto('\\:')|0) | "*.*") prefix := reverse(tab(0)) } Whereas he himself used: fnr := reverse(pfn) k := upto("\\:", fnr) | *fnr + 1 prefix := reverse(fnr[k:0]) name := "" ~== reverse(fnr[1:k]) | "*.*" I'm not at all sure which is clearer or stylistically better. The first, however, runs about 12% faster on filenames with no path pre- pended. On files with a long path, the difference goes down to about 3% or even 1%. Anyone have any thoughts on why? Anyone have any thoughts on icon programming style in general? -Richard L. Goerwitz goer@sophist.uchicago.edu rutgers!oddjob!gide!sophist!goer From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Sun Jan 22 20:12:58 1989 Received: from mailgw.cc.umich.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA18414; Sun, 22 Jan 89 20:12:58 MST Received: from umix.cc.umich.edu by mailgw.cc.umich.edu (5.59/1.0) id AA29168; Sun, 22 Jan 89 22:08:23 EST Received: by umix.cc.umich.edu (5.54/umix-2.0) id AA20308; Sun, 22 Jan 89 22:13:59 EST Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Sun, 22 Jan 89 22:10:54 EST Date: Sun, 22 Jan 89 20:26:28 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@arizona.edu Message-Id: <112392@Wayne-MTS> Subject: DOS filename generator I think that Richard's parser of the filename is much more elegant than mine. I was just trying to get the job done quickly. The time is irrelevant since the generator is hardly likely to be used in an inner loop. Writing the generator actually raised another interesting question of style. The int86 function wants a list of nine items. What I would really like to do, however, is to define: record registers(int_nbr, ax, bx, cx, dx, si, di, es, ds) params := record() every !params := 0 record.int_nbr := ... # etc. for the other nontrivial components and then pass params to Int86. But Int86 wants a list of nine items -- nothing else will do. It would be nice if I could write: Int86(list(params)) but that's not legal as far as I know. Is there an elegant way to convert params to the list that I want? About the best I could come up with was: l := list(9, 0) g1 := create !params g2 := create !l while @g2 := @g1 Int86(l) Paul Abrahams From kwalker Mon Jan 23 14:28:36 1989 Date: Mon, 23 Jan 89 14:28:36 MST From: "Kenneth Walker" Message-Id: <8901232128.AA02752@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA02752; Mon, 23 Jan 89 14:28:36 MST In-Reply-To: <93400002@uicbert.eecs.uic.edu> To: icon-group Subject: Re: data backtracking, more general con from Paul R. Wilson: > From: uxg.cso.uiuc.edu!uicbert.eecs.uic.edu!wilson@uxc.cso.uiuc.edu > Subject: data backtracking, more general con > > Is anyone working on an Icon-like language with more orthogonal > control structures and data types? Is anyone working on a more > general expression evaluation mechanism? > > I've figured out how to accomplish general data backtracking in a garbage > collected heap, and in fact how to extend it to "sidetracking." (More than > one subexpression may execute simultaneously, with each isolated > from the others' side effects. The parent expression can choose to keep the > side effects of at most one of the subexpressions.) This can be done with > a certain amount of continual overhead on stock hardware, and probably with > negligible overhead on Lisp machines. Have you looked at parallel execution of Prolog and other logic prgramming languages? > What I'm mostly looking for is ideas of what a language with such powerful > facilities should look like. Icon strikes me as a sort of hodgepodge > of features and types, but the particular combinations of features and > types seem to work remarkably well together. You use backtracking where > appropriate, and assemble the rest as an imperative program. I would say that Icon works well, because, in spite of some very important innovations, it is based mostly on features that have proven their usefulness. For example, the data types integer, real, (true) string, list (really vector and queue, just combined), table, record, and set all have a history of extensive use. The majority of operations follow directly from the needs of the data types, though there are some exceptions. Most of Icon's control structures are based on the ones commonly found in traditional languages and that many programmers would feel sifled without. Actually, you should view backtracking (control backtracking, not data backtracking) as a pervasive feature of the language, though, of course, many individual operations are deterministic in nature. This backtracking is then "bounded" by various control structures. This bounding typically occurs the the control structures that try to mimic those of conventional languages. Several control structures (every, suspend, |, \) make use of this goal-directed evaluation, but there is currently no underlying model of the control structures possible in the presence of backtracking. > Icon's simple backtracking mechanism may be as complex a predefined > evaluation mechanism as you'd want, since a more general mechanism > wouldn't give you enough familiar idioms to be able to make sense of > a program. On the other hand, a multiway mechanism seems very valuable > if it is truly parallel, so a certain extra complexity is doubtless > worthwhile. [text deleted] > What would you want control constructs to look like, if you could have > anything you wanted? This question has two sides -- one for language > prototyping, and one for language use. What should a very general > evaluation mechanism be like, to enable the prototyping of things > like backtracking? What set of fixed or default mechanisms would you > want if you could only pick a couple of simple ones to actually use > in programs all the time? The U of A Technical Report TR82-16a, "Programmer Defined Evaluation Regimes" by Michael Novak and Ralph E. Griswold explores some of these questions. They use co-expressions as an implementation tool. This turns out to be somewhat awkward, but is adaquate for experimentation. In fact, Programmer Defined Control Operations (PDCOs) is a feature in the distributed versions of Icon that support co-expressions. Kelvin Nilsen added concurrent processes to Icon, based on co-expressions. His work is described in his dissertation, which is available as TR88-30, "The Design and Implementation of High-Level Programming Language Features for Pattern Matching in Real Time". If you are interested in a more theoretical framework for goal-directed evaluation and Icon-style control structures, you might look at TR86-15, "A Continuation Semantics For Icon Expressions" by David Gudeman. On the other hand, a more "systems" approach can be found in Janalee O'Bagy's dissertation. It is available as TR88-31, "The Implemantation of Generators and Goal-Directed Evaluation in Icon". There are some obvious (?) ways to extend Icon's evaluation scheme. You can generalize generators to full co-routines or extend goal-directed evaluation from a sylized use of success and failure continuations to fully general use of continuations, but it is not clear that these are directions you want to take. Sometime too much power can get in your way. The above technical reports are available through the Icon Project: icon-project@arizona.edu {uunet|allegra|noao}!arizona!icon-project Icon Project Department of Computer Science Gould-Simpson Building The University of Arizona Tucson, AZ 85721 Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621 2858 kwalker@Arizona.EDU {uunet|allegra|noao}!arizona!kwalker From dscargo@cim-vax.honeywell.com Thu Jan 26 14:07:05 1989 Message-Id: <8901262107.AA22065@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA22065; Thu, 26 Jan 89 14:07:05 MST Date: 26 Jan 89 15:03:00 CST From: "DAVE CARGO" Subject: two-dimensional arrays To: "icon-group" Is there any concensus on the best way to simulate two-dimensional arrays in Icon? It might be that I need to have a table of tables. My particular application requires keeping counts associated with states of origin by different conventions. So I've got a cross product of states (by abbreviation) and conventions (a three character code). dsc From ralph Thu Jan 26 14:24:05 1989 Date: Thu, 26 Jan 89 14:24:05 MST From: "Ralph Griswold" Message-Id: <8901262124.AA23177@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA23177; Thu, 26 Jan 89 14:24:05 MST To: dscargo@cim-vax.honeywell.com Subject: Re: two-dimensional arrays Cc: icon-group In-Reply-To: <8901262107.AA22065@megaron.arizona.edu> If your array is sparse, I'd use a table of tables. If it's dense, I'd use a list of lists. If it's in between, you might might want a list of tables or a table of lists, depending. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From spqr%electronics-and-computer-science.southampton.ac.uk@NSS.Cs.Ucl.AC.UK Wed Feb 1 02:04:44 1989 Received: from NSS.CS.UCL.AC.UK by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA20535; Wed, 1 Feb 89 02:04:44 MST Received: from electronics-and-computer-science.southampton.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP id aa03051; 1 Feb 89 8:40 GMT From: Sebastian Rahtz Date: Wed, 1 Feb 89 08:54:26 GMT Message-Id: <11636.8902010854@hilliard.ecs.soton.ac.uk> To: icon-group@arizona.edu Cc: dder%electronics-and-computer-science.southampton.ac.uk@NSS.Cs.Ucl.AC.UK Subject: on the fly procedure definition I must apologize to the people who contributed their thoughts on why Icon cannot generate a completely new procedure at runtime; I went away immediately after posting my query, and only just returned. I cannot see an immediate answer to my problem, though I am grateful to Bill Griswold for another working example of a co-expression (one of those things I lie awake at night pondering). As a follow up, can I ask gurus to confirm that a) dynamic linking is impossible, unless you are Ken Walker. So I can't even do a system("icont -c ...") etc ? b) there is no chance of a vast Icon run-time system appearing with a translator and linker present? c) I can't convert a string to a variable (if you see what I mean)? Thus if I have a program: .. foo("set","a","hello") write(foo("get","a")) .. procedure foo(message,var,text) static a,b,c case message of { "set" : case var of { "a" : a:=text "b" : b:=text "c" : c:=text } "get" : case var of { "a" : return a "b" : return b "c" : return c } } return end ... my program duly writes "hello"; but I want to avoid the inner case constructs and when I pass foo "a" have it look at variable a. It seems to me that I cannot do this, except by listing all the static variables in a static table (ie have a table 'vars' with an entry vars["a"]:=a, and then referring to vars[var].) But that means I have to list out all the static variables again in the table, with concomitant possibility of error. Can I acquire a list of the variables in a procedure, in the manner of display()? And yes, I am doing this out of a purist desire to avoid global variables. Sebastian Rahtz. Computer Science, Southampton, UK. spqr@uk.ac.soton.ecs From wgg@june.cs.washington.edu Wed Feb 1 12:38:45 1989 Received: from june.cs.washington.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA18810; Wed, 1 Feb 89 12:38:45 MST Received: by june.cs.washington.edu (5.59/6.13+) id AA01865; Wed, 1 Feb 89 11:37:18 PST Date: Wed, 1 Feb 89 11:37:18 PST From: wgg@june.cs.washington.edu (William Griswold) Return-Path: Message-Id: <8902011937.AA01865@june.cs.washington.edu> To: icon-group@arizona.edu Subject: Re: on the fly procedure definition This is a preliminary response to Sebastian Rahtz's question on dynamic features in Icon. Corrections from the Home Office would be appreciated. >From: Sebastian Rahtz Date: Wed, 1 Feb 89 08:54:26 GMT >To: icon-group@arizona.edu >Subject: on the fly procedure definition > >I must apologize to the people who contributed their thoughts on why >Icon cannot generate a completely new procedure at runtime; I went away >immediately after posting my query, and only just returned. I cannot see >an immediate answer to my problem, though I am grateful to Bill Griswold >for another working example of a co-expression (one of those things I >lie awake at night pondering). As a follow up, can I ask gurus to >confirm that > > a) dynamic linking is impossible, unless you are Ken Walker. So I can't > even do a system("icont -c ...") etc ? You cannot in the current system. I have built a dynamic linker for Icon, but it isn't the most integrated design possible, and it hurts the performance of the interpreter a bit. I haven't upgraded it to version 7, either. As I (think) I said in earlier messages, it can be done, and done efficiently, but it's a lot of work. > b) there is no chance of a vast Icon run-time system appearing with > a translator and linker present? I have no doubt that it is possible. It's been done for Lisp, and it's just a program, after all. It would be a lot of work to implement it, however, and the program would be rather large. For example, the executable program for Franz Lisp on my machine is about 1 megabyte. Icon wouldn't be that big (probably not much bigger than the sum of the sizes of all the executables for Icon now), but you get the idea. > c) I can't convert a string to a variable (if you see what I mean)? In Icon you can't convert a string to a variable, but you can convert a string to a procedure (but not a procedure variable, I believe). It probably wouldn't be too hard to implement an operator or function that did the equivalent of foo, however. In my implementation of a dynamic linker for Icon, a newly linked file can link to any existing variables, and introduce new ones as well (which files linked later can refer to). However, a file cannot all-of-a-sudden reference variables that it had no idea existed before. This is not a damaging restriction because I can still convert strings to procedures, so older parts of the program can *call* newly introduced procedures. From my experience procedural extension works just fine, and doesn't cramp my style at all. > Thus if I have a program: > .. > foo("set","a","hello") > write(foo("get","a")) > .. > procedure foo(message,var,text) > static a,b,c > case message of > { > "set" : > case var of > { > "a" : a:=text > "b" : b:=text > "c" : c:=text > } > "get" : > case var of > { > "a" : return a > "b" : return b > "c" : return c > } > } > return > end > ... > > my program duly writes "hello"; but I want to avoid the inner case >constructs and when I pass foo "a" have it look at variable a. It seems >to me that I cannot do this, except by listing all the static variables >in a static table (ie have a table 'vars' with an entry vars["a"]:=a, and >then referring to vars[var].) But that means I have to list out all the >static variables again in the table, with concomitant possibility of error. Of course, if someone wanted to refer to a normal variable in the normal way, or through the table, the result should be the same, so you're back to using the case statement for these variables. >Can I acquire a list of the variables in a procedure, in the >manner of display()? Right now the implementation of Icon does not allow for a ``variable'' type per-se; you could get the name of a variable, or its value, but not a reference to the variable itself. I suspect its addition could complicate the language: does addition of two variables mean the addition of the variables' values? Would the only operation on variables be ``get'' and ``set''? Or would you introduce an explicit dereferencing operator for variables, and if so could it mean anything to other types? You could refer back to SNOBOL on this, which has a lot of the features you're looking for and more. I think it's more trouble than it's worth. > >And yes, I am doing this out of a purist desire to avoid global variables. > >Sebastian Rahtz. Computer Science, Southampton, UK. >spqr@uk.ac.soton.ecs > Bill Griswold From @NSS.Cs.Ucl.AC.UK,@electronics-and-computer-science.southampton.ac.uk:spqr@computer-science.southampton.ac.uk Thu Feb 2 08:59:39 1989 Received: from NSS.CS.UCL.AC.UK by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA29082; Thu, 2 Feb 89 08:59:39 MST Received: from electronics-and-computer-science.southampton.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP id aa04480; 2 Feb 89 13:22 GMT From: Sebastian Rahtz Received: from caxton.cm.soton.ac.uk by hilliard.ecs.soton.ac.uk; Thu, 2 Feb 89 13:37:40 GMT Date: Thu, 2 Feb 89 13:38:38 GMT Message-Id: <3805.8902021338@caxton.cm.soton.ac.uk> To: wgg@june.cs.washington.edu Cc: icon-group@arizona.edu In-Reply-To: William Griswold's message of Wed, 1 Feb 89 11:37:18 PST <8902011937.AA01865@june.cs.washington.edu> Subject: on the fly procedure definition thanks for the thoughts; i'll concentrate on things Icon is good at, rather than complaining about things it doesn't have! refer back to SNOBOL on this, which has a lot of the features you're looking for and more. I think it's more trouble than it's worth. yes but Snobol isnt half as much fun as Icon! anyway, the fact that you have built a dynamic linker suggests to me that you have identified a gap in the implementation yourself? i think one thing that bothers me is that Icon has the bad points of a compiled language (ie the dynamic features are gone), but doesnt have the virtue of generating standalone code. But thats an old debate which I think Arizona have answered quite clearly. Sebastian Rahtz. Computer Science, Southampton, UK. spqr@uk.ac.soton.ecs From R21014@UQAM.BITNET Tue Feb 7 09:12:04 1989 Message-Id: <8902071612.AA03629@megaron.arizona.edu> Received: from rvax.ccit.arizona.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA03629; Tue, 7 Feb 89 09:12:04 MST Received: from UQAM.BITNET by rvax.ccit.arizona.edu; Tue, 7 Feb 89 08:40 MST Received: by UQAM (Mailer X1.25) id 9573; Tue, 07 Feb 89 10:25:40 EST Date: Tue, 07 Feb 89 10:24:42 EST From: Luc Dupuy Subject: Icon Compiler To: Icon-Group I see in "The Icon Programming Language" some reference to an Icon Compiler; is there such a compiler for version 7.5? thank you. From ralph Tue Feb 7 09:31:02 1989 Date: Tue, 7 Feb 89 09:31:02 MST From: "Ralph Griswold" Message-Id: <8902071631.AA04603@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA04603; Tue, 7 Feb 89 09:31:02 MST To: R21014@UQAM.BITNET Subject: Re: Icon Compiler Cc: icon-group In-Reply-To: <8902071612.AA03629@megaron.arizona.edu> Early versions of Icon supported a "compiler", which is mentioned in the Icon book. However, it mostly generated subroutine calls and was only 5-10% faster than the interpreter. Since there was little speed advantage and the compiler was much less portable than the interpreter, we stopped supporting the compiler some time ago. Version 7.5 only provides an interpreter. We are working on a true, production-quality compiler for Icon, but this is presently in the research stage and we have no projections for when such an implementation might be available. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From sboisen@REGULUS.BBN.COM Tue Feb 7 11:39:19 1989 Message-Id: <8902071839.AA12576@megaron.arizona.edu> Received: from REGULUS.BBN.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA12576; Tue, 7 Feb 89 11:39:19 MST To: icon-group@arizona.edu Subject: GNU Emacs documenter for Icon (LONG) From: Sean Boisen Sender: sboisen@REGULUS.BBN.COM Reply-To: sboisen@bbn.com Date: Tue, 7 Feb 89 13:26:04 EST This is a quick syntax helper for Icon users that work with GNU Emacs. The idea is a simple one: while creating a program, say, you're unsure about the arguments or their orders for push(). With icon-describe, you simple execute the function "describe-icon-symbol" with point somewhere around the word push, and the following information is displayed in the mini-buffer: push(list,x) This works with procedures, infix/prefix operators, control structures/reserved words, and keywords. Note that you get notified if something isn't in the documentation file, so you can also use it to check whether you've got the right symbol name or not (but you'd have to go look to see what the _right_ one is :-). Caveats: See your Emacs manual for how to load this automatically when you visit .icn files (look at auto-mode-alist and icon-mode-hook, assuming you're using an icon-mode). describe-icon-symbol is not initially bound to a key, but you'll probably want to do so. The format of the documentation file is one to a line: this is nice because it can be displayed in the minibuffer instead of a pop-up which then has to be gotten rid of. It's not so nice in that it limits the amount of information pretty severely. If somebody wants to provide a larger documentation file i might provide a pop-up version (or some hybrid): i'm too lazy to do all the typing, for one thing! There's also an uneven mix of bare syntax description with some discussion of what (especially prefix) operators do. A few keywords have no description because they're newer than the Icon book, and i didn't have a description handy. Please contribute to this doc file if you can! The function which determines the symbol at point isn't perfect (surprise surprise!). In particular it depends on the syntax tables to determine what punctuation is, so if your syntax tables aren't right, this won't be either. I'm open to suggestions for better algorithms. The current version has a preference for looking backward if not actually on part of a symbol: this seemed more useful for those cases where you become hesitant about the arguments to a function just after typing it. While the usual lack of warranty and support applies, i'd still like to hear if there are problems with this. Sean Boisen sboisen@bbn.com BBN Systems and Technologies Corporation Two files follow: i call the first icon-describe.el (don't forget to byte-compile it!), and the second icondoc.txt. Whatever you decide to call the latter, make sure you set the variable doc-file accordingly! -------------------- cut here for icon-describe.el -------------------- ;;; Icon syntax describer: by Sean Boisen, BBN Systems and ;;; Technologies Corporation, sboisen@bbn.com. Standard lack of ;;; warranty applies: may be freely distributed subject to the ;;; restrictions of the GNU Emacs copyright. Please send me any bug ;;; fixes and/or improvements! ;;; ;;; This still has at least the following known deficiences: ;;; ;;; The descriptive text file lacks descriptions for the newer ;;; keywords. Please add them and send me a version if you can! ;;; ;;; It might be nice if icon-symbol-at-point did escape sequences as ;;; well: it doesn't. ;;; ;;; Someday it might be more useful to provide more than one line of ;;; information, especially for procedures: the main hurdle here is ;;; that i'm too lazy to type all the text in. (provide 'icon-describe) (defvar doc-file "/usr/sboisen/emacs/icondoc.txt" "Where the documentation file can be found.") ;; a helper function: get a string containing all the characters matching ;; some spec in a syntax table. Class is an atom. Useful in conjunction with ;; skip-chars-forward. Doesn't do the eighth bit. (defun get-chars-in-class (class syntax-table) (let ((classcode (cond ((eq class 'whitespace) 0) ((eq class 'punctuation) 1) ((eq class 'word) 2) ((eq class 'symbol) 3) ((eq class 'open) 4) ;this doesn't work! ((eq class 'close) 5) ((eq class 'prefix) 6) ((eq class 'stringquote) 7) ((eq class 'charquote) 9) ((eq class 'startcomment) 11) ((eq class 'endcomment) 12) )) (index 0) (str "")) (while (< index 128) (if (eql (aref syntax-table index) classcode) (setq str (concat str (char-to-string index)))) (setq index (1+ index))) str)) (defvar wordchars "a-zA-Z0-9_") (defvar junkchars (concat " \n\t\r" "({[)}]")) (defvar punct (get-chars-in-class 'punctuation icon-mode-syntax-table)) (defun icon-symbol-at-point () "Get the closest Icon symbol to point, but don't change your position. Has a preference for looking backward when not directly on a symbol." (let (start end symbol) (save-excursion ;; first see if you're just past a symbol (if (looking-at "\\s-\\|\\s(\\|\\s)\\|\\s>") (skip-chars-backward junkchars) ;; else move forward one character, presumably either a \w or ;; a symbol (forward-char 1)) (if (eql (aref icon-mode-syntax-table (preceding-char)) 2) ;; just past a \\w (progn (skip-chars-backward wordchars) (setq start (point)) (skip-chars-forward wordchars)) ;; else a symbol? (progn (skip-chars-backward punct) (setq start (point)) (skip-chars-forward punct))) ;; THE OLD WAY THAT LOOKED FORWARD INSTEAD OF BACKWARD ;; ;; skip past whitespace and parens ;; (while (looking-at "\\s-\\|\\s(\\|\\s)\\|\\s>") ;; (skip-chars-forward junkchars)) ;; (if (looking-at "\\w") ;; (progn ;; (skip-chars-forward wordchars) ;; (setq start (point)) ;; (skip-chars-backward wordchars)) ;; ;; else a symbol? ;; (progn ;; (skip-chars-forward punct) ;; (setq start (point)) ;; (skip-chars-backward punct))) (buffer-substring start (point))))) (defun describe-icon-symbol (symbol) "Display the documentation of SYMBOL, an Icon operator." (interactive (let ((fn (icon-symbol-at-point)) (enable-recursive-minibuffers t) (case-fold-search nil) ;require that case match for search val args-file regexp) (setq val (read-from-minibuffer (if fn (format "Symbol (default %s): " fn) "Symbol: "))) (if (string= val "") (setq val fn)) ;; this may not work for characters which are special to regexp ;; (like ".") (setq regexp (concat "^" val "[ \t(]")) (if (not (get-file-buffer doc-file)) (progn (setq args-file (find-file-noselect doc-file)) (set-buffer args-file) (rename-buffer "*ICON-DOC*"))) (set-buffer (get-file-buffer doc-file)) (goto-char (point-min)) (list (if (re-search-forward regexp (point-max) t) (save-excursion (beginning-of-line 1) (let ((lnstart (point))) (end-of-line) (message (buffer-substring lnstart (point))))) (error (format "No definition for %s" val))))))) -------------------- cut here for icondoc.txt -------------------- FORMAT: a regexp like "^word(args)" of "^word[\t ]descriptive_text abs(numeric) any(cset,string,i,j) bal(cset1,cset2,cset3,string,i,j) center(string1,i,string2) char(i) close(file) collect() copy(x) cset(x) delete(x1,x2) detab(string,i1,i2,...,in) display(i,file) entab(string,i1,i2,...,in) errorclear() exit(i) find(string1,string2,i,j) get(list) getenv(string) iand(i,j) icom(i) image(x) insert(x1,x2,x3) integer(x) ior(i,j) ixor(i,h) ishift(i,j) left(string1,i,string2) list(i,x) many(cset,string,i,j) map(string1,string2,string3) match(string1,string2,i,j) member(x1,x2) move(i) numeric(x) open(string1,string2) ord(string) pop(list) pos(i) proc(x) pull(list) push(list,x) put(list,x) read(file) reads(file,i) real(x) remove(string) rename(string1,string2) repl(string,i) reverse(string) right(string1,i,string2) runerr(i,x) save(string) seek(file,i) seq(i,j) set(list) sort(list) sort(table,i) stop(x1,x2,...,xn) string(x) system(string) tab(i) table(x) trim(string,cset) type(x) upto(cset,string,i,j) where(file) write(x1,x2,...,xn) writes(x1,x2,...,xn) CONTROL STRUCTURES/RESERVED WORDS break expr by i to j by k case expr of {...} create x default : expr do every expr1 do expr2; until expr1 do expr2; while expr1 do expr2 dynamic identifiers else if expr1 then expr2 else expr3 end every expr1 do expr2 fail global identifiers if expr1 then expr2 else expr3 initial expr link file1,file2,...filen local identifiers next not expr of case expr of {...} procedure identifier(identifiers) record identifiers(fields) repeat expr return expr static identifiers suspend expr then if expr1 then expr2 else expr3 to i to j by k until expr1 do expr2 while expr1 do expr2 | expr1 | expr2; |expr \ expr \ i ; \x produces x if x is not null, otherwise fails ?:= s ?:= x ? s ? x; ?x produces a random element of x, failing if x is empty INFIX OPERATIONS + n + m produces the sum of n and m; +n produces the numeric value of n - n - m produces the difference of n and m; -n produces the negative of n * n * m produces the product of n and m; *x produces the size of x / n / m produces n divided by m; /x produces x if x is null, or else fails % n % m produces the remainder of n divided by m ^ n ^ m produces n to the power of m; ^e produces a refreshed copy of e < n < m produces m if n is less than m, else fails <= n <= m produces m if n is less than or equal to m, else fails = n = m produces m if n equals m, else fails; =s equiv. to tab(match(s)) >= n >= m produces m if n is greater than or equal to m, else fails > n > m produces m if n is greater than m, else fails ~= n ~= m produces m if n is not equal to m, else fails ++ c1 ++ c2 produces the cset union of c1 and c2 -- c1 -- c2 produces the cset difference of c1 and c2 ** c1 ** c2 produces the cset intersection of c1 and c2 || s1 || s2 produces a string consisting of s1 followed by s2 << s1 << s2 produces s2 if s1 is lexically less than s2, else fails <<= s1 <<= s2 produces s2 if s1 is lexically <= s2, else fails == s1 == s2 produces s2 if s1 is lexically equal to s2, else fails >>= s1 >>= s2 produces s2 if s1 is lexically >= s2, else fails >> s1 >> s2 produces s2 if s1 is lexically greater than s2, else fails ~== s1 ~== s2 produces s2 if s2 isn't lexically equal to s2, else fails ||| a1 ||| a2 produces a list of the values of a1 followed by those of a2 @ x @ e activates e and transmits x to it; @e produces the outcome of activating e := x := y assigns the value of y to x, and produces the variable x <- x <- y assigns y to x and produces x; reverses assignment if resumed :=: x :=: y exchanges the values of x and y and produces the variable x <-> x <-> y exchanges x and y and produces x; reverses exchange if resumed === x === y produces y if x and y have the same value, else fails ~=== x ~=== y produces y if x and y don't have the same value, else fails & x & y produces y; produces a variable if y is a variable . x . y produces a variable for the y field of record x +:= n +:= m assigns the sum of n and m to n and produces n -:= n -:= m assigns the difference of n and m to n and produces n *:= n *:= m assigns the product of n and m to n and produces n /:= n /:= m assigns the difference of n and m to n and produces n %:= n %:= m assigns the remainder of n divided by m to n and produces n ^:= n ^:= m assigns n raised to the power m to n and produces n <:= n <:= m assigns m to n if n < m, else fails; produces n <=:= n <=:= m assigns m to n if n <= m, else fails; produces n =:= n =:= m assigns m to n if n = m, else fails; produces n >=:= n >=:= m assigns m to n if n >= m, else fails; produces n >:= n >:= m assigns m to n if n > m, else fails; produces n ~=:= n ~=:= m assigns m to n if n ~= m, else fails; produces n ++:= c1 ++:= c2 assigns the cset union of c1 and c2 to c1 and produces c1 --:= c1 --:= c2 assigns the cset difference of c1 and c2 to c1, producing c1 **:= c1 **:= c2 assigns the intersection of c1 and c2 to c1, producing c1 ||:= s1 ||:= s2 assigns the string s1 || s2 to s1 and produces s1 <<:= s1 <:= s2 assigns s2 to s1 if s1 << s2, else fails; produces s1 <<=:= s1 <=:= s2 assigns s2 to s1 if s1 <<= s2, else fails; produces s1 ==:= s1 =:= s2 assigns s2 to s1 if s1 == s2, else fails; produces s1 >>=:= s1 >=:= s2 assigns s2 to s1 if s1 >>= s2, else fails; produces s1 >>:= s1 >:= s2 assigns s2 to s1 if s1 >> s2, else fails; produces s1 ~==:= s1 ~=:= s2 assigns s2 to s1 if s1 ~== s2, else fails; produces s1 |||:= a1 |||:= a2 assigns to a1 the concatenation of a1 and a2; produces a1 @:= x @:= e activates e with the value of x, and assigns the result to x ===:= x ===:= y assigns y to x if x === y, else fails; produces x ~===:= x ~===:= y assigns y to x if x ~=== y, else fails; produces x &:= x &:= y assigns the value of y to x and produces x PREFIX OPERATIONS (some under infix instead) ~ ~c produces the cset complement of c with respect to &cset ! !x generates the elements of x, failing if x is empty (x may be a file) . .x produces the value of x KEYWORDS &ascii produces a cset of the 128 ASCII characters &clock produces a string consisting of the current time of day &collections &cset produces a cset consisting of all 256 characters ¤t &date produces a string consisting of the current date &dateline produces a string of the current date and time of day &digits &error &errornumber &errortext &errorvalue &errout produces the standard error output file &fail fails &features &file &host produces a string that identifies the host computer &input produces the standard input file &lcase produces a cset consisting of the 26 lowercase letters &level produces the integer level of the current procedure call &line &main produces a co-expression for the initial call of main &null produces the null value &output produces the standard output file &pos produces the integer position of scanning in &subject &random produces the value of the seed for the psuedo-random sequence ®ions &source produces a co-expression for the activator of the current co-expression &storage how much of each storage region is currently being used &subject produces the variable whose value is the string being scanned &time produces the integer number of msecs since beginning of execution &trace produces a variable whose value controls procedure tracing &ucase produces a cset consisting of the 26 uppercase characters &version produces a string that identifies the version of Icon -------------------- cut here: no more -------------------- From @UICVM.uic.edu:EM302723@VMTECMEX.BITNET Tue Feb 7 12:33:05 1989 Message-Id: <8902071933.AA16028@megaron.arizona.edu> Received: from uicvm.cc.uic.edu.2.248.128.in-addr.arpa by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA16028; Tue, 7 Feb 89 12:33:05 MST Received: from VMTECMEX.BITNET by UICVM.uic.edu (IBM VM SMTP R1.2) with BSMTP id 1395; Tue, 07 Feb 89 13:27:55 CST Date: Tue, 07 Feb 89 13:16:43 MEX To: icon-group@arizona.edu From: EM302723%VMTECMEX.BITNET@UICVM.uic.edu Comment: CROSSNET mail via SMTP@INTERBIT Subject: Extension Interpreter request Date: 7 February 89, 13:14:51 MEX From: Mario Camou Riveroll EM302723 at VMTECMEX To: ICON-GROUP at ARIZONA A few Icon Newsletters ago I read about an 'extension interpreter' which was under development and supposed to let you call C functions without modifying the compiler. What's the status on it? -Mario Camou EM302723@VMTECMEX.BITNET From ralph Tue Feb 7 12:53:18 1989 Date: Tue, 7 Feb 89 12:53:18 MST From: "Ralph Griswold" Message-Id: <8902071953.AA16991@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA16991; Tue, 7 Feb 89 12:53:18 MST To: EM302723%VMTECMEX.BITNET@UICVM.uic.edu Subject: Re: Extension Interpreter request Cc: icon-group In-Reply-To: <8902071933.AA16028@megaron.arizona.edu> The Extension Interpreter is a larger project at the University of Washington, part of which required calling C functions from Icon and vice-versa. The modifications to Icon for this are included in the Version 7.5 source code, but they've not been tested yet. You'll probably hear more on this subject from the author of the Icon modifications, Bill Griswold. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From sboisen@IZAR.BBN.COM Tue Feb 7 16:29:22 1989 Message-Id: <8902072329.AA29277@megaron.arizona.edu> Received: from IZAR.BBN.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA29277; Tue, 7 Feb 89 16:29:22 MST To: icon-group@arizona.edu Subject: why you shouldn't make last minute changes to your code! From: Sean Boisen Sender: sboisen@IZAR.BBN.COM Reply-To: sboisen@bbn.com Date: Tue, 7 Feb 89 18:21:15 EST Sorry folks, a minor error in the code i just sent out: all occurrences of "doc-file" in icon-describe.el should be replaced with "icon-doc-file". ........................................ Sean Boisen -- sboisen@bbn.com BBN Systems and Technologies Corporation, Cambridge MA Disclaimer: these opinions void where prohibited by lawyers. From sboisen@REGULUS.BBN.COM Wed Feb 8 07:41:43 1989 Message-Id: <8902081441.AA04963@megaron.arizona.edu> Received: from REGULUS.BBN.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA04963; Wed, 8 Feb 89 07:41:43 MST To: mwb5y <@bbn.com:mwb5y@uvacs.cs.virginia.edu> Cc: icon-group@arizona.edu In-Reply-To: "Mark W. Bailey"'s message of Wed, 8 Feb 89 09:28:46 EST <8902081428.AA13060@uvacs.cs.virginia.edu> Subject: Icon mode from emacs From: Sean Boisen Sender: sboisen@REGULUS.BBN.COM Reply-To: sboisen@bbn.com Date: Wed, 8 Feb 89 9:36:55 EST > Date: Wed, 8 Feb 89 09:28:46 EST > From: "Mark W. Bailey" > Posted-Date: Wed, 8 Feb 89 09:28:46 EST > > > Sean, > I received your icon documenter and it looks great. However, I > am in need of icon-mode...I assume you have one, could you forward > this to me? > > Mark Bailey > > mwb5y@virginia Expecting others may be interested, here's my icon-mode: i may have mangled the original to suit my tastes, so don't blame Chris Smith if you find fault (maybe if Chris is listening he could post his original? or at least check). This appears to be modeled after c-mode, so if you find your indentation tastes offended you ought to be able to make the icon variables follow the ones for C (i happen to like these values just fine). ........................................ Sean Boisen -- sboisen@bbn.com BBN Systems and Technologies Corporation, Cambridge MA Disclaimer: these opinions void where prohibited by lawyers. ==================== cut here for icon-mode.el ==================== ;; Icon code editing commands for Emacs ;; Derived from c-mode.el 15-Apr-88 Chris Smith convex!csmith ;; Copyright (C) 1988 Free Software Foundation, Inc. ;; This file is part of GNU Emacs. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY. No author or distributor ;; accepts responsibility to anyone for the consequences of using it ;; or for whether it serves any particular purpose or works at all, ;; unless he says so in writing. Refer to the GNU Emacs General Public ;; License for full details. ;; Everyone is granted permission to copy, modify and redistribute ;; GNU Emacs, but only under the conditions described in the ;; GNU Emacs General Public License. A copy of this license is ;; supposed to have been given to you along with GNU Emacs so you ;; can know your rights and responsibilities. It should be in a ;; file named COPYING. Among other things, the copyright notice ;; and this notice must be preserved on all copies. (defvar icon-mode-abbrev-table nil "Abbrev table in use in Icon-mode buffers.") (define-abbrev-table 'icon-mode-abbrev-table ()) (defvar icon-mode-map () "Keymap used in Icon mode.") (if icon-mode-map () (setq icon-mode-map (make-sparse-keymap)) (define-key icon-mode-map "{" 'electric-icon-brace) (define-key icon-mode-map "}" 'electric-icon-brace) (define-key icon-mode-map "\e\C-h" 'mark-icon-function) (define-key icon-mode-map "\e\C-a" 'beginning-of-icon-defun) (define-key icon-mode-map "\e\C-e" 'end-of-icon-defun) (define-key icon-mode-map "\e\C-q" 'indent-icon-exp) (define-key icon-mode-map "\177" 'backward-delete-char-untabify) (define-key icon-mode-map "\t" 'icon-indent-command)) (defvar icon-mode-syntax-table nil "Syntax table in use in Icon-mode buffers.") (if icon-mode-syntax-table () (setq icon-mode-syntax-table (make-syntax-table)) (modify-syntax-entry ?\\ "\\" icon-mode-syntax-table) (modify-syntax-entry ?# "<" icon-mode-syntax-table) (modify-syntax-entry ?\n ">" icon-mode-syntax-table) (modify-syntax-entry ?$ "." icon-mode-syntax-table) (modify-syntax-entry ?/ "." icon-mode-syntax-table) (modify-syntax-entry ?* "." icon-mode-syntax-table) (modify-syntax-entry ?+ "." icon-mode-syntax-table) (modify-syntax-entry ?- "." icon-mode-syntax-table) (modify-syntax-entry ?= "." icon-mode-syntax-table) (modify-syntax-entry ?% "." icon-mode-syntax-table) (modify-syntax-entry ?< "." icon-mode-syntax-table) (modify-syntax-entry ?> "." icon-mode-syntax-table) (modify-syntax-entry ?& "." icon-mode-syntax-table) (modify-syntax-entry ?| "." icon-mode-syntax-table) (modify-syntax-entry ?\' "\"" icon-mode-syntax-table)) (defconst icon-indent-level 4 "*Indentation of Icon statements with respect to containing block.") (defconst icon-brace-imaginary-offset 0 "*Imagined indentation of a Icon open brace that actually follows a statement.") (defconst icon-brace-offset 0 "*Extra indentation for braces, compared with other text in same context.") (defconst icon-continued-statement-offset 4 "*Extra indent for lines not starting new statements.") (defconst icon-continued-brace-offset 0 "*Extra indent for substatements that start with open-braces. This is in addition to icon-continued-statement-offset.") (defconst icon-auto-newline nil "*Non-nil means automatically newline before and after braces, and after colons and semicolons, inserted in C code.") (defconst icon-tab-always-indent t "*Non-nil means TAB in Icon mode should always reindent the current line, regardless of where in the line point is when the TAB command is used.") (defun icon-mode () "Major mode for editing Icon code. Expression and list commands understand all Icon brackets. Tab indents for Icon code. Paragraphs are separated by blank lines only. Delete converts tabs to spaces as it moves back. \\{icon-mode-map} Variables controlling indentation style: icon-tab-always-indent Non-nil means TAB in Icon mode should always reindent the current line, regardless of where in the line point is when the TAB command is used. icon-auto-newline Non-nil means automatically newline before and after braces inserted in Icon code. icon-indent-level Indentation of Icon statements within surrounding block. The surrounding block's indentation is the indentation of the line on which the open-brace appears. icon-continued-statement-offset Extra indentation given to a substatement, such as the then-clause of an if or body of a while. icon-continued-brace-offset Extra indentation given to a brace that starts a substatement. This is in addition to icon-continued-statement-offset. icon-brace-offset Extra indentation for line if it starts with an open brace. icon-brace-imaginary-offset An open brace following other text is treated as if it were this far to the right of the start of its line. Turning on Icon mode calls the value of the variable icon-mode-hook with no args, if that value is non-nil." (interactive) (kill-all-local-variables) (use-local-map icon-mode-map) (setq major-mode 'icon-mode) (setq mode-name "Icon") (setq local-abbrev-table icon-mode-abbrev-table) (set-syntax-table icon-mode-syntax-table) (make-local-variable 'paragraph-start) (setq paragraph-start (concat "^$\\|" page-delimiter)) (make-local-variable 'paragraph-separate) (setq paragraph-separate paragraph-start) (make-local-variable 'indent-line-function) (setq indent-line-function 'icon-indent-line) (make-local-variable 'require-final-newline) (setq require-final-newline t) (make-local-variable 'comment-start) (setq comment-start "# ") (make-local-variable 'comment-end) (setq comment-end "") (make-local-variable 'comment-column) (setq comment-column 32) (make-local-variable 'comment-start-skip) (setq comment-start-skip "# *") (make-local-variable 'comment-indent-hook) (setq comment-indent-hook 'icon-comment-indent) (run-hooks 'icon-mode-hook)) ;; This is used by indent-for-comment ;; to decide how much to indent a comment in Icon code ;; based on its context. (defun icon-comment-indent () (if (looking-at "^#") 0 ;Existing comment at bol stays there. (save-excursion (skip-chars-backward " \t") (max (1+ (current-column)) ;Else indent at comment column comment-column)))) ; except leave at least one space. (defun electric-icon-brace (arg) "Insert character and correct line's indentation." (interactive "P") (let (insertpos) (if (and (not arg) (eolp) (or (save-excursion (skip-chars-backward " \t") (bolp)) (if icon-auto-newline (progn (icon-indent-line) (newline) t) nil))) (progn (insert last-command-char) (icon-indent-line) (if icon-auto-newline (progn (newline) ;; (newline) may have done auto-fill (setq insertpos (- (point) 2)) (icon-indent-line))) (save-excursion (if insertpos (goto-char (1+ insertpos))) (delete-char -1)))) (if insertpos (save-excursion (goto-char insertpos) (self-insert-command (prefix-numeric-value arg))) (self-insert-command (prefix-numeric-value arg))))) (defun icon-indent-command (&optional whole-exp) (interactive "P") "Indent current line as Icon code, or in some cases insert a tab character. If icon-tab-always-indent is non-nil (the default), always indent current line. Otherwise, indent the current line only if point is at the left margin or in the line's indentation; otherwise insert a tab. A numeric argument, regardless of its value, means indent rigidly all the lines of the expression starting after point so that this line becomes properly indented. The relative indentation among the lines of the expression are preserved." (if whole-exp ;; If arg, always indent this line as Icon ;; and shift remaining lines of expression the same amount. (let ((shift-amt (icon-indent-line)) beg end) (save-excursion (if icon-tab-always-indent (beginning-of-line)) (setq beg (point)) (forward-sexp 1) (setq end (point)) (goto-char beg) (forward-line 1) (setq beg (point))) (if (> end beg) (indent-code-rigidly beg end shift-amt "#"))) (if (and (not icon-tab-always-indent) (save-excursion (skip-chars-backward " \t") (not (bolp)))) (insert-tab) (icon-indent-line)))) (defun icon-indent-line () "Indent current line as Icon code. Return the amount the indentation changed by." (let ((indent (calculate-icon-indent nil)) beg shift-amt (case-fold-search nil) (pos (- (point-max) (point)))) (beginning-of-line) (setq beg (point)) (cond ((eq indent nil) (setq indent (current-indentation))) ((eq indent t) (setq indent (calculate-icon-indent-within-comment))) ((looking-at "[ \t]*#") (setq indent 0)) (t (skip-chars-forward " \t") (if (listp indent) (setq indent (car indent))) (cond ((and (looking-at "else\\b") (not (looking-at "else\\s_"))) (setq indent (save-excursion (icon-backward-to-start-of-if) (current-indentation)))) ((or (= (following-char) ?}) (looking-at "end\\b")) (setq indent (- indent icon-indent-level))) ((= (following-char) ?{) (setq indent (+ indent icon-brace-offset)))))) (skip-chars-forward " \t") (setq shift-amt (- indent (current-column))) (if (zerop shift-amt) (if (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos))) (delete-region beg (point)) (indent-to indent) ;; If initial point was within line's indentation, ;; position after the indentation. Else stay at same point in text. (if (> (- (point-max) pos) (point)) (goto-char (- (point-max) pos)))) shift-amt)) (defun calculate-icon-indent (&optional parse-start) "Return appropriate indentation for current line as Icon code. In usual case returns an integer: the column to indent to. Returns nil if line starts inside a string, t if in a comment." (save-excursion (beginning-of-line) (let ((indent-point (point)) (case-fold-search nil) state containing-sexp toplevel) (if parse-start (goto-char parse-start) (setq toplevel (beginning-of-icon-defun))) (while (< (point) indent-point) (setq parse-start (point)) (setq state (parse-partial-sexp (point) indent-point 0)) (setq containing-sexp (car (cdr state)))) (cond ((or (nth 3 state) (nth 4 state)) ;; return nil or t if should not change this line (nth 4 state)) ((and containing-sexp (/= (char-after containing-sexp) ?{)) ;; line is expression, not statement: ;; indent to just after the surrounding open. (goto-char (1+ containing-sexp)) (current-column)) (t ;; Statement level. Is it a continuation or a new statement? ;; Find previous non-comment character. (if toplevel (progn (icon-backward-to-noncomment (point-min)) (if (icon-is-continuation-line) icon-continued-statement-offset 0)) (if (null containing-sexp) (progn (beginning-of-icon-defun) (setq containing-sexp (point)))) (goto-char indent-point) (icon-backward-to-noncomment containing-sexp) ;; Now we get the answer. (if (icon-is-continuation-line) ;; This line is continuation of preceding line's statement; ;; indent icon-continued-statement-offset more than the ;; first line of the statement. (progn (icon-backward-to-start-of-continued-exp containing-sexp) (+ icon-continued-statement-offset (current-column) (if (save-excursion (goto-char indent-point) (skip-chars-forward " \t") (eq (following-char) ?{)) icon-continued-brace-offset 0))) ;; This line starts a new statement. ;; Position following last unclosed open. (goto-char containing-sexp) ;; Is line first statement after an open-brace? (or ;; If no, find that first statement and indent like it. (save-excursion (if (looking-at "procedure\\s ") (forward-sexp 3) (forward-char 1)) (while (progn (skip-chars-forward " \t\n") (looking-at "#")) ;; Skip over comments following openbrace. (forward-line 1)) ;; The first following code counts ;; if it is before the line we want to indent. (and (< (point) indent-point) (current-column))) ;; If no previous statement, ;; indent it relative to line brace is on. ;; For open brace in column zero, don't let statement ;; start there too. If icon-indent-level is zero, ;; use icon-brace-offset + icon-continued-statement-offset instead. ;; For open-braces not the first thing in a line, ;; add in icon-brace-imaginary-offset. (+ (if (and (bolp) (zerop icon-indent-level)) (+ icon-brace-offset icon-continued-statement-offset) icon-indent-level) ;; Move back over whitespace before the openbrace. ;; If openbrace is not first nonwhite thing on the line, ;; add the icon-brace-imaginary-offset. (progn (skip-chars-backward " \t") (if (bolp) 0 icon-brace-imaginary-offset)) ;; here we are (current-indentation)))))))))) (defun icon-is-continuation-line () (let* ((ch (preceding-char)) (ch-syntax (char-syntax ch))) (if (eq ch-syntax ?w) (assoc (buffer-substring (progn (forward-word -1) (point)) (progn (forward-word 1) (point))) '(("do") ("dynamic") ("else") ("initial") ("link") ("local") ("of") ("static") ("then"))) (not (memq ch '(0 ?\; ?\} ?\{ ?\) ?\] ?\" ?\' ?\n)))))) (defun icon-backward-to-noncomment (lim) (let (opoint stop) (while (not stop) (skip-chars-backward " \t\n\f" lim) (setq opoint (point)) (beginning-of-line) (if (and (search-forward "#" opoint 'move) (< lim (point))) (forward-char -1) (setq stop t))))) (defun icon-backward-to-start-of-continued-exp (lim) (if (memq (preceding-char) '(?\) ?\])) (forward-sexp -1)) (while (icon-is-continued-line) (end-of-line 0)) (beginning-of-line) (if (<= (point) lim) (goto-char (1+ lim))) (skip-chars-forward " \t")) (defun icon-is-continued-line () (save-excursion (end-of-line 0) (icon-is-continuation-line))) (defun icon-backward-to-start-of-if (&optional limit) "Move to the start of the last ``unbalanced'' if." (or limit (setq limit (save-excursion (beginning-of-icon-defun) (point)))) (let ((if-level 1) (case-fold-search nil)) (while (not (zerop if-level)) (backward-sexp 1) (cond ((looking-at "else\\b") (setq if-level (1+ if-level))) ((looking-at "if\\b") (setq if-level (1- if-level))) ((< (point) limit) (setq if-level 0) (goto-char limit)))))) (defun mark-icon-function () "Put mark at end of Icon function, point at beginning." (interactive) (push-mark (point)) (end-of-icon-defun) (push-mark (point)) (beginning-of-line 0) (beginning-of-icon-defun)) (defun beginning-of-icon-defun () "Go to the start of the enclosing procedure; return t if at top level." (interactive) (if (re-search-backward "^procedure\\s \\|^end[ \t\n]" (point-min) 'move) (looking-at "e") t)) (defun end-of-icon-defun () (interactive) (if (not (bobp)) (forward-char -1)) (re-search-forward "\\(\\s \\|^\\)end\\(\\s \\|$\\)" (point-max) 'move) (forward-word -1) (forward-line 1)) (defun indent-icon-exp () "Indent each line of the Icon grouping following point." (interactive) (let ((indent-stack (list nil)) (contain-stack (list (point))) (case-fold-search nil) restart outer-loop-done inner-loop-done state ostate this-indent last-sexp at-else at-brace at-do (opoint (point)) (next-depth 0)) (save-excursion (forward-sexp 1)) (save-excursion (setq outer-loop-done nil) (while (and (not (eobp)) (not outer-loop-done)) (setq last-depth next-depth) ;; Compute how depth changes over this line ;; plus enough other lines to get to one that ;; does not end inside a comment or string. ;; Meanwhile, do appropriate indentation on comment lines. (setq innerloop-done nil) (while (and (not innerloop-done) (not (and (eobp) (setq outer-loop-done t)))) (setq ostate state) (setq state (parse-partial-sexp (point) (progn (end-of-line) (point)) nil nil state)) (setq next-depth (car state)) (if (and (car (cdr (cdr state))) (>= (car (cdr (cdr state))) 0)) (setq last-sexp (car (cdr (cdr state))))) (if (or (nth 4 ostate)) (icon-indent-line)) (if (or (nth 3 state)) (forward-line 1) (setq innerloop-done t))) (if (<= next-depth 0) (setq outer-loop-done t)) (if outer-loop-done nil (if (/= last-depth next-depth) (setq last-sexp nil)) (while (> last-depth next-depth) (setq indent-stack (cdr indent-stack) contain-stack (cdr contain-stack) last-depth (1- last-depth))) (while (< last-depth next-depth) (setq indent-stack (cons nil indent-stack) contain-stack (cons nil contain-stack) last-depth (1+ last-depth))) (if (null (car contain-stack)) (setcar contain-stack (or (car (cdr state)) (save-excursion (forward-sexp -1) (point))))) (forward-line 1) (skip-chars-forward " \t") (if (eolp) nil (if (and (car indent-stack) (>= (car indent-stack) 0)) ;; Line is on an existing nesting level. ;; Lines inside parens are handled specially. (if (/= (char-after (car contain-stack)) ?{) (setq this-indent (car indent-stack)) ;; Line is at statement level. ;; Is it a new statement? Is it an else? ;; Find last non-comment character before this line (save-excursion (setq at-else (looking-at "else\\W")) (setq at-brace (= (following-char) ?{)) (icon-backward-to-noncomment opoint) (if (icon-is-continuation-line) ;; Preceding line did not end in comma or semi; ;; indent this line icon-continued-statement-offset ;; more than previous. (progn (icon-backward-to-start-of-continued-exp (car contain-stack)) (setq this-indent (+ icon-continued-statement-offset (current-column) (if at-brace icon-continued-brace-offset 0)))) ;; Preceding line ended in comma or semi; ;; use the standard indent for this level. (if at-else (progn (icon-backward-to-start-of-if opoint) (setq this-indent (current-indentation))) (setq this-indent (car indent-stack)))))) ;; Just started a new nesting level. ;; Compute the standard indent for this level. (let ((val (calculate-icon-indent (if (car indent-stack) (- (car indent-stack)))))) (setcar indent-stack (setq this-indent val)))) ;; Adjust line indentation according to its contents (if (or (= (following-char) ?}) (looking-at "end\\b")) (setq this-indent (- this-indent icon-indent-level))) (if (= (following-char) ?{) (setq this-indent (+ this-indent icon-brace-offset))) ;; Put chosen indentation into effect. (or (= (current-column) this-indent) (progn (delete-region (point) (progn (beginning-of-line) (point))) (indent-to this-indent))) ;; Indent any comment following the text. (or (looking-at comment-start-skip) (if (re-search-forward comment-start-skip (save-excursion (end-of-line) (point)) t) (progn (indent-for-comment) (beginning-of-line)))))))))) From wgg@june.cs.washington.edu Wed Feb 8 13:05:05 1989 Received: from june.cs.washington.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA23818; Wed, 8 Feb 89 13:05:05 MST Received: by june.cs.washington.edu (5.59/6.13+) id AA05068; Wed, 8 Feb 89 12:02:14 PST Date: Wed, 8 Feb 89 12:02:14 PST From: wgg@june.cs.washington.edu (William Griswold) Return-Path: Message-Id: <8902082002.AA05068@june.cs.washington.edu> To: EM302723%VMTECMEX.BITNET@UICVM.uic.edu Subject: Re: Extension Interpreter request Cc: icon-group@arizona.edu >Date: Tue, 07 Feb 89 13:16:43 MEX >To: icon-group@arizona.edu >From: EM302723%VMTECMEX.BITNET@UICVM.uic.edu >Comment: CROSSNET mail via SMTP@INTERBIT >Subject: Extension Interpreter request > >Date: 7 February 89, 13:14:51 MEX >From: Mario Camou Riveroll EM302723 at VMTECMEX >To: ICON-GROUP at ARIZONA > >A few Icon Newsletters ago I read about an 'extension interpreter' which >was under development and supposed to let you call C functions without >modifying the compiler. What's the status on it? > >-Mario Camou >EM302723@VMTECMEX.BITNET > The Extension Interpreter is a research prototype. Although work is continuing on the EI (I am building new applications on top of the EI, and I'm adding C++ to the list of languages it supports), there is no intent to distribute it. The EI is not an Icon-specific tool (Icon is one of the languages it supports), but it is Unix specific in that the C dynamic loader works on the Berkeley object format. The Icon C-calling feature itself is fully portable. On the Icon side, The C-calling feature is on the list of things to be added to Icon (some of the hooks are there), but time is scarce. It probably won't get done unless there is sufficient interest. Bill Griswold From icon-group-request Thu Feb 9 04:47:18 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA11778; Thu, 9 Feb 89 04:47:18 MST Received: by ucbvax.Berkeley.EDU (5.61/1.33) id AA29644; Thu, 9 Feb 89 03:26:09 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 8 Feb 89 17:33:15 GMT From: grand!day@uunet.uu.net (Dave Yost) Organization: Grand Software, Inc., Los Angels, CA 213-650-1089 Subject: Re: Icon Compiler Message-Id: <478@grand.UUCP> References: <8902071612.AA03629@megaron.arizona.edu>, <8902071631.AA04603@megaron.arizona.edu> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu In article <8902071631.AA04603@megaron.arizona.edu> ralph@ARIZONA.EDU ("Ralph Griswold") writes: >Early versions of Icon supported a "compiler", which is mentioned in >the Icon book. However, it mostly generated subroutine calls and >was only 5-10% faster than the interpreter. As an Icon fan who would like to see it spread, I offer this: The speed advantage is only one goal of a compiler. Another important one is to be able to generate a self-contained single executable, preferably as small as possible because it contains only the runtime routines it needs. If one could do this, then one could build a binary of an icon program for someone who has the same machine but doesn't want to commit to installing the icon interpreter. Ideally, it would be nice to get a tape with icon runtime libraries for all machines in some machine independent format and have the ability to generate binaries for many different machines without having to have those machines and without requiring that the icon interpreter be installed separately on a user's machine. I believe Icon would spread faster if it were easier to give someone an Icon program you wrote, at least in binary form for them to try out. As it is now, you have to convince them to install a major language system for them to be able to use some little tool you whipped up in Icon. I have found monumental resistance to installing *some weirdo nonstandard [fill in your own xenolingophobic epithets] language*. People don't even want to install a ready-made interpreter in their file system. Maybe if we could hand out runnable binaries of our useful Icon programs then maybe they would listen when we tell them how it was so much easier to write in Icon and would have never been written at all if it had to be done in C. And I conclude with a prayer. May some great organization see the wisdom in giving nice grants to the deserving Icon Group. --dave From sunquest!whm Thu Feb 9 10:35:54 1989 Received: by megaron.arizona.edu (5.59-1.7/15) id AA28047; Thu, 9 Feb 89 10:35:54 MST Date: Thu, 9 Feb 89 10:29:33 MST From: "Bill Mitchell" Message-Id: <8902091729.AA07281@sunquest> Received: by sunquest; Thu, 9 Feb 89 10:29:33 MST To: arizona!icon-group Subject: Re: Icon Compiler Well, you can make standalone executables with the save() function with a minimum of trouble. However, they're pretty big -- I just tried one and got about a 340k file. I compressed that and got down to about 100k, but that's still a lot. I wonder if it would work to ship someone a copy of the interpreter and then have a program to change the location of the interpreter in the icode file. That would be two programs that one could stick in one's bin and then you could send around icode files for machines of the same architecture. However, with only five files (icont, itran, ilink, iconx.hdr, and iconx), you can have a complete Icon system and then just ship around Icon source files. I think that it's really just a packaging problem -- there just needs to be a way to clone a minimal Icon system from an installed system. Of course, solving packaging problems isn't research. (Unless you're an industrial engineer??) -------------------------------------------------------------------- Bill Mitchell whm@sunquest.com Sunquest Information Systems sunquest!whm@arizona.edu Tucson, AZ {arizona,uunet}!sunquest!whm 602-885-7700 From sunquest!arizona!ralph Thu Feb 9 11:19:04 1989 Received: by megaron.arizona.edu (5.59-1.7/15) id AA01123; Thu, 9 Feb 89 11:19:04 MST Received: by sunquest; Thu, 9 Feb 89 11:12:41 MST Date: Thu, 9 Feb 89 11:08:39 MST From: "Ralph Griswold" Message-Id: <8902091808.AA00547@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA00547; Thu, 9 Feb 89 11:08:39 MST To: sunquest!arizona!icon-group, sunquest!whm Subject: Re: Icon Compiler In-Reply-To: <8902091729.AA07281@sunquest> The save() function is presently available only on BSD UNIX versions of Icon and I don't see it being much help except in certain very special kinds of environments. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From icon-group-request Thu Feb 9 11:19:46 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA01144; Thu, 9 Feb 89 11:19:46 MST Received: by ucbvax.Berkeley.EDU (5.61/1.33) id AA05994; Thu, 9 Feb 89 10:16:17 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 8 Feb 89 11:51:51 GMT From: mcvax!hp4nl!mhres!jv@uunet.uu.net (Johan Vromans) Organization: Multihouse NV, the Netherlands Subject: GNU Emacs Icon mode Message-Id: <2862@mhres.mh.nl> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu Does someone have a GNU Emacs electric-icon mode? Or other Icon-specialized editing environment? [Yes, I did receive the recently posted "describe-icon-symbol" command for GNU Emacs. Thank you.] -- Johan Vromans jv@mh.nl via european backbone (mcvax) Multihouse [A-Za-z ]* [NB]V uucp: ..!mcvax!mh.nl!jv Gouda - The Netherlands phone: +31 1820 62944 From att!ihuxy!nowlin Thu Feb 9 13:04:24 1989 Date: Thu, 9 Feb 89 13:04:24 MST Message-Id: <8902092004.AA07470@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA07470; Thu, 9 Feb 89 13:04:24 MST Received: by att.ATT.COM (smail2.6 - att-ih) id AA01172; 9 Feb 89 14:01:01 CST (Thu) From: ihuxy!nowlin (Jerry D Nowlin +1 312 979 0441) To: att!arizona!icon-group Subject: Re: Icon Compiler (files needed) At AT&T we (Rick Fonorow and myself) have had to modify Icon in order to install it in a semi-official place on all the R&D systems in the Naperville Area. The result of this is that only two files are needed for a complete Icon system, icont and iconx. These files can be placed in any directory that's in a users PATH (a UNIX environment is needed) and the user has Icon. This makes for a much easier system to distribute to a lot of machines. I think the Icon Project has agreed to include these modifications in a future release. They'll have to confirm that though. Jerry Nowlin (...!att!ihuxy!nowlin) From spqr%electronics-and-computer-science.southampton.ac.uk@NSS.Cs.Ucl.AC.UK Fri Feb 10 01:32:43 1989 Received: from NSS.CS.UCL.AC.UK by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA11047; Fri, 10 Feb 89 01:32:43 MST Received: from electronics-and-computer-science.southampton.ac.uk by NSS.Cs.Ucl.AC.UK via Janet with NIFTP id aa03525; 10 Feb 89 8:03 GMT From: Sebastian Rahtz Date: Fri, 10 Feb 89 08:23:32 GMT Message-Id: <14993.8902100823@hilliard.ecs.soton.ac.uk> To: icon-group@arizona.edu Subject: whats in a name Its really trivial of me, and nosey, but what is the relationship between Bill Griswold and Ralph Griswold? sebastian rahtz From sboisen@REGULUS.BBN.COM Tue Feb 14 12:54:07 1989 Message-Id: <8902141954.AA26787@megaron.arizona.edu> Received: from REGULUS.BBN.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA26787; Tue, 14 Feb 89 12:54:07 MST To: unido!infbs!neitzel <@bbn.com:unido!infbs!neitzel@UUNET.UU.NET> Cc: icon-group@arizona.edu Subject: GNU Emacs -- icon-*.el bug(s) From: Sean Boisen Sender: sboisen@REGULUS.BBN.COM Reply-To: sboisen@bbn.com Date: Tue, 14 Feb 89 14:50:09 EST Martin Neitzel pointed out a bug to me: if point is at the end of the buffer, it errors out. This can be fixed as follows: replace, in icon-symbol-at-point (line 67 in my version) (forward-char 1) with (or (= (point) (point-max)) (forward-char 1)) There is also a problem in the icon-mode i posted with indentation: auto-filled comments get an extra space at the beginning of subsequent lines. # so that comments like this # turn out this ugly way I tried to figure this out once but couldn't come up with anything. We now return to your regularly scheduled content.... ........................................ Sean Boisen -- sboisen@bbn.com BBN Systems and Technologies Corporation, Cambridge MA Disclaimer: these opinions void where prohibited by lawyers. From dscargo@cim-vax.honeywell.com Thu Feb 16 09:39:21 1989 Message-Id: <8902161639.AA04530@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA04530; Thu, 16 Feb 89 09:39:21 MST Date: 16 Feb 89 10:19:00 CST From: "DAVE CARGO" Subject: table default values To: "icon-group" Must be time for another strange idea from the frozen north. I was looking at tables, this time for the purpose of doing some ASCII to PostScript conversion. Most characters are fine, but there are some that need to be escaped or otherwise translated. There are lots of mechanisms for doing this, but most of them are something of a pain to set up. Would it be reasonable to have the default value for table() have a way of knowing that the default assigned value for an entry value should be the entry value? Depending on you point of view this might be something like translations := table(&self) or maybe translations := table(&entry_value) Once again, it's because the programs I write do lots of mapping that makes me want to find easy ways of mapping a single input byte to a potentially multibyte output. Map won't do what I want. I suppose I could take each input character, convert it to an integer, and then use that as an index into a list. That sounds like it would generate lots of garbage; I'm also concerned that the list access might be slower than the table access (which I suppose I could actual test). Anybody else have common single char to multichar mapping problems? Do you use tables or some other mechanisms? From gudeman Thu Feb 16 10:18:03 1989 Date: Thu, 16 Feb 89 10:18:03 MST From: "David Gudeman" Message-Id: <8902161718.AA06968@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA06968; Thu, 16 Feb 89 10:18:03 MST To: dscargo@cim-vax.honeywell.com Cc: icon-group@arizona.edu In-Reply-To: "DAVE CARGO"'s message of 16 Feb 89 10:19:00 CST <8902161639.AA04530@megaron.arizona.edu> Subject: table default values >Date: 16 Feb 89 10:19:00 CST >From: "DAVE CARGO" >...[wants to have the default value for a table be the entry key]... I suppose you are aware of this method: t := table() ... elem := \t[elem] | elem >Would it be reasonable to have the default value for table() have a >way of knowing that the default assigned value for an entry value >should be the entry value?... > >translations := table(&entry_value) I like that idea. It would also be nice to have keywords like &new_list -- produces a new list for default values &new_table -- produces a new table for default values &new_set -- produces a new set for default values From wgg@june.cs.washington.edu Thu Feb 16 13:20:37 1989 Received: from june.cs.washington.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA16994; Thu, 16 Feb 89 13:20:37 MST Received: by june.cs.washington.edu (5.59/6.13+) id AA05346; Thu, 16 Feb 89 12:18:47 PST Date: Thu, 16 Feb 89 12:18:47 PST From: wgg@june.cs.washington.edu (William Griswold) Return-Path: Message-Id: <8902162018.AA05346@june.cs.washington.edu> To: icon-group@arizona.edu Subject: Re: table default values >Date: 16 Feb 89 10:19:00 CST >From: "DAVE CARGO" >Subject: table default values >To: "icon-group" > >Must be time for another strange idea from the frozen north. I was looking >at tables, this time for the purpose of doing some ASCII to PostScript >conversion. Most characters are fine, but there are some that need to >be escaped or otherwise translated. There are lots of mechanisms for doing >this, but most of them are something of a pain to set up. Would it be >reasonable to have the default value for table() have a way of knowing that >the default assigned value for an entry value should be the entry value? > >Depending on you point of view this might be something like > >translations := table(&self) > >or maybe > >translations := table(&entry_value) As mentioned in the previous message, one way of solving this problem is by saying (\translations[value] | value) # may be resumed if outer # expression fails! however, if used as a general expression, you might prefer: {\translations[value] | value} # won't be resumed if outer # expression fails or by encapuslating the code in a procedure to prevent resumption. If efficiency is your thing, you can iterate through &cset before doing your multi-byte assignments; translations := table() every translations[v := !&cset] := v # multi-byte mappings... and then lookup would revert to mapping := translations[char] These lookups won't return null unless the input isn't a single character string. >Once again, it's because the programs I write do lots of mapping that makes >me want to find easy ways of mapping a single input byte to a potentially >multibyte output. Map won't do what I want. I suppose I could take each >input character, convert it to an integer, and then use that as an index >into a list. That sounds like it would generate lots of garbage; I'm also >concerned that the list access might be slower than the table access >(which I suppose I could actual test). > >Anybody else have common single char to multichar mapping problems? Do >you use tables or some other mechanisms? > You might find that performing list lookup on the ord of the input value is faster, since hashing and chaining won't be performed. The code might look like this: translations := list(*&cset) every translations[ord(v := !&cset] := v # multi-byte mappings... and lookups would look like mapping := translations[ord(char)] Bill Griswold From dscargo@cim-vax.honeywell.com Mon Feb 20 11:10:12 1989 Message-Id: <8902201810.AA07072@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA07072; Mon, 20 Feb 89 11:10:12 MST Date: 19 Feb 89 09:46:00 CST From: "DAVE CARGO" Subject: tables and &self To: "icon-group" I found another circumstance where the table(&self) would have been useful, though it would have been a generalization of what I suggested last time. In particular, I was needing to sort some records according to the magnitude of one of their components. In this case, a generalization of what I had before, to_be_sorted := table(&self.magnitude) .... insert(to_be_sorted,appropriate_record) Granted there are many problems with this. The initialization of the table is really producing some kind of a "thunk". It's code that isn't evaluated until an insertion is performed. The original &self is a relatively trivial thunk, equivalent to identity. Going beyond that adds more complex expressions that are evaluated at insertion time, whose results are used as the assigned values. Partly I wanted to avoid initializing a table composed mostly of identities. I can see that what I have above might almost be better served by user-defined functions that do something like Insert(to_be_sorted,appropriate_record,appropriate_record.magnitude) In many cases this would work well enough, but it still doesn't give me my avoidance of initialization except for exceptional cases. dsc From icon-group-request Mon Feb 20 11:13:36 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA07261; Mon, 20 Feb 89 11:13:36 MST Received: by ucbvax.Berkeley.EDU (5.61/1.34) id AA19833; Sat, 18 Feb 89 02:35:58 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 16 Feb 89 17:49:10 GMT From: mcvax!hp4nl!kunivv1!atcmpe!gertjan@uunet.uu.net (Gertjan Vinkesteyn) Organization: AT Computing, Nijmegen, The Netherlands Subject: Re: Icon Lectures Part 3/3 Message-Id: <483@atcmpe.atcmp.nl> References: <481@atcmpe.atcmp.nl>, <482@atcmpe.atcmp.nl> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh icon/course/course08.29 <<'END_OF_icon/course/course08.29' XIn the previous note I forgot to mention that there is homework as well. XThe homework for 8-27 was : Read Chapter 1-3 in the ICON book. X XCourse 8/29 X XTechnical Aspects of ICON: X- automatic storage management X- no declaration of variables, no partition, varying size, runtime creation X XCharacteristics: X- high level programming oriented X- non-numerical scientific computation X- novel, experimental features X- less regard for efficiency than facility X- pointer semantic to structures X XThere are many types, but no type declaration - variables are 'untyped' XRun-time type system (late-binding) as opposed to compile type system. XThere is strong run-time type checking and automatic conversion. XScoping is static (for that is clear and simple) X XThe syntax is expession based. In Algol like languages you have Xdistinction between statements and expressions. A negative aspect of Xexpression based syntax is : where does the compiler make localisation Xof syntax errors (least of Griswold's concern). X XIcon has traditional control structures, not like Snobol, but like Algol. XThere are some novel control structures. XA large repertoir of operations and functions, especially on strings. XThere are some "extra" features: X- string scanning (analog to pattern matching in Snobol4) X- co-expressions XSnobol has extensive dynamic binding, more then Icon. Because most Xprograms are incorrect any way verification is not important :-) X XGetting Started with Icon: X========================== XThe most important declaration is the 'procedure'. Like in C programs Xneed to start with a 'procedure main()' XThere are i/o write and read function (this is a nice side-effect which Xis not always available in Functional Languages!) X XEssential is the expression evaluation mechanism. An expression may X succeed == produces a result X fail == produces not a result XE.g. X while line:=read() do write(line) X Xis driven by success or failure of line:=read() XYou can see it as :=(line,read()) Xif read() fails the assignment is not performed. XThis is different than in Algol like languages because if X while line:=read() Xfails then 'line' will still holds its old value, that is not changed XA site effect is that you really better always check function calls Xbecause if you have written somewhere X line:=read() Xthen the program can 'fail' without letting you know where! XIn Algol line:=read() is a boolean expression X XEvery expression delivers a value Xi > j delivers the value of 'j' Xi > j > k works then okay because it is like (i > j) > k and works as Xaspected. You can write that in most language but they don't do what you Xthink they should do. XAlso k := i > j for your own ideocratic programming style. X XAlmost ever operator has an augmented assigment version. XLike i +:= j delivers i := i + j but in one step (internally) XThe operator set is fixed and cannot be changed like in Algol68 and XSnobol4. That is done mainly for machine convenience, it could be part Xof the language. There are 68 different kind of operators like x ~===:= y Xis on page 273 in the Icon book. X XFunctions are data-objects which values can be changed. That is used to Xpass functions as parameters to procedures. XSo you never really know if X while line:=read() Xis what you think it is. If you have written somewhere in the beginning Xof your programming X read:=write Xthen you might be in big trouble! But that does not happen too often in Xthis case. X XSo a lot is dependent on your own programming style and social conduct. XThat is the responsibility of the writer not of the language. X XHOMEWORK: Read Chapter 4 X XThe biggest chapter with a lot of details. END_OF_icon/course/course08.29 if test 3603 -ne `wc -c icon/course/course09.03 <<'END_OF_icon/course/course09.03' XToday Ralph started to talk about homework. An interesting point is that Xhe uses a background program to check your homework in your directory X~/550 (550 is the course number). Just a quote out if his handout for the Xfun of it: X X The demon usually will be unleashed just before class on the day X homework is due. The demon will be annoyed if it does not find X a file with the expected name. Half a program is considerably X better than none. The demon will be infuriated if your program X loops endlessly. It is unwise to infuriate a demon. It is better X to have a program that commits hari-kiri than one that runs amok. X ... X The grading of the homework will depend on the quality of solutions X as well as their correctness. As the course develops, we will discuss X good "idiomatic" Icon. To start, make your best guess as to what X constitutes good style in Icon. X XOf course you cannot hand in your homework but in that case please send Xit in to me ('mail gertjan') and I will check it for you. X XHOMEWORK Assignment 1 - Due Thursday, September 12, 1985 X X1. (nest.icn, 10 pts) Do Exercise 2.8 from the Icon book. You may assume Xthat all braces in the input file are syntactically meaningful - that Xnone are quoted, for example. X X2. (case.icn, 10 pts) Write a program that counts the number of Xuppercase and lowercase letters in the standard input file, and then Xprints the counts and their ratio. X X3. (palin.icn, 10 pts) Do Exercise 4.8 in the Icon book. Supply a main Xprogram that reads lines from standard input and filters out any lines Xthat are not palindromic sentences. X X=== X XIcon is not designed to be a production oriented language. XTranslation in to executable code goes very fast for a virtual machine. X XThere are different ways representing data. XIn Icon strings are ATOMIC, they are not arrays of characters. XThere is no operation in Icon what can change a character in a string. XStrings can be very long and are only dependent of your amount of X(virtual) memory in your hardware. XSo operations on strings are applicative. X XThere is no char data type. XIn Icon the characters are 8-bits long independent of machine type. So Xthere are 256 different characters. (ed. this is not easy to change to Xtwo-byte or three-byte character code, see note of Ralph about that) XThese 256 chars have an ASCII representation. So "a" -> 01100001 XThat is also on an IBM EBCDIC machine! The {null} character can be used Xas any ordinary character (it is not an eos marker like in C). X XSingle quotes are used to enclose character sets. XThese are "sets" of characters and called: csets X XSize of 'abc' represented as *'abc' -> 3 X *'aaa' -> 1 and *'' -> 0 (the empty set) XThere are some predefined sets like: &lcase :=: 'a b c d ... z' Xothers are &ucase, &ascii (7-bits ascii set), &cset (the whole 256 range) X XConverting of a set to a string will cause the characters to appear as Xan ASCII collating sequence. X XStrings are represented in "double quotes". The amount of strings is Xconceptually infinite. XConcatenation: s1 || s2 produces a NEW data object XHow do you identify subsequences (linguistically spoken) XEg. X s := "Front" Positions are between X -5 -4 -3 -2 -1 0 characters, they can never X F r o n t cut characters in parts. X 1 2 3 4 5 6 XPositive in respect to the first character. Negative or zero to the last data X XSo a substring goes from [2:-2] -> "ro" XA substring is done with two indices hold in square braces: X s[i:j] X s[0:2] # for right to left data X s[2:0] XIf any of these indices are outside the string it will 'fail' which is Xnot an error and can be checked on. XEg. s[-2] == s[4] s[i] == s[i:i+1] (i>0) s[i+:j] == s[i:i+1] X Xs := "Front" then s[2] := "xy" will result in s := "Fxyont" XYou can delete a character by s[i] := "" XThis looks like a change of char in a string: it is not! X XExample: X i:=3 s:="Front" X j:=i t:=s X i:=i+1 s[2]:="xy" XYou don't expect that the value of the integer 'j' will be changed so Xneither will 't'. Xt:=s is a shorthand notation, it will never effect the string 's'; XSo not like in C. If the assignment would really copy the string than Xyou would not worry about it. It is, however, pointer oriented. X XThe Icon memory is in fact one big string, being extented at the end and Xhaving pointers all over the place. X XComparing strings X s1 == s2 "a" is lexicographically less than "aA" X s1 ~== s2 Xpage 33 has the six lexical operators. X X End-of-course.9-3 END_OF_icon/course/course09.03 if test 4428 -ne `wc -c icon/course/course09.10 <<'END_OF_icon/course/course09.10' XRemember: everything what is not understood in these notes is X probably due to my typing (gertjan) X XGood Tuesday 11am Rm 321 Comp Sc building Univ. of Arizona, Tucson XProf. Ralph Griswold teaches X XSome remarks about homework: Think Unix, that means do it terse, X only do what have been X asked and supply a main procedure X so that it can run! X XString construction operators -> return string, cannot fail X----------------------------- X s1 || s2 reverse(s) X read(s1, s2) trim(s, c) X right( ) map(s1, s2, s3) X left( ) X XString analisys operation -> return number (index), it may fail X------------------------- X{you will actually hardly use the number, but use these X procedures as parameters to other procedures} X X find(s1, s2) match(s1, s2) X XThe remaining operations deal with character sets X------------------------------------------------- Xupto(c, s) reads upto (before) the first char in s in cset c Xany(c, s) produces the position after the first char in s is X the first char c, or fail Xmany(c, s) same as 'any', but any char in c will do Xbal(c1,c2,c3,c4) a little horror X XKeep in mind that 'bal' is 'upto' with 2 additional args. Eg: Xbal('+-*/', '(', ')', "(a+(c-d))") fails Xbal('+-*/', '(', ')', "(a+(c-d))*d") succeeds and leaves index here | X ^___________________________________| Xthe optional arguments, here '(' and ')', are optional char sets and set Xdefault to '(' and ')'. X XLeft to right scanning is inheritated and part of all these Xprocedures, like in english. It can be done right to left by Xrewriting these procedures. Icon provides the tools for that with Xits C interfacing (Personalized Icon). XA good thing at least is that the positions are always between Xcharacters, so at least that is consistent to left and right. X XStructures X========== XThese are really aggregates of variables, or values. There are X X lists these are like vectors, so not like in LISP X tables set of pair of values, like fruit["apple"] := 2 X records like the records in PASCAL X sets not mentioned in the book, part of Icon 5.9 and up *) X this are unordered collections of values and have the X properties normally associated with sets in the X mathematical sense. X X{ At the beginning of each course we install a new version of XIcon, so you get 5.10 now. But we are not going to send it out of Xtown before the end of the course! } X X*) I will try to get a copy of TR85-16 which gives an overview of X5.10 and send it over (gertjan). Ask Larry Versaw for "Extensions Xto Version 5 of the Icon Programming Language", TR-84-10b, that Xtalks about sets. X XLists are linear, accessed positions. Eg. X X a1 := [exp1, exp2, ..., expn] X a2 := list(i, expr) X like in a1 := [read(), 10, s1 || s2] X XSize operations succeed on lists as well, *a1 -> 3 (polymorphic) XIndex referencing goes like in arrays X a1[2] subscribes the list X write(a1[2]) writes 10 Xlast subscript can be written as -1, a1[-1] -> s1 || s2 X X a1 ||| a2 three vertical bars concatenates lists X a3 := a1 ||| a2 constructs a totally new list X a4 := a3[2:4] [1, 2, "x", 13.7] -> [2, "x"] X XInteresting in lists are queue and stack acceses X X push(a, x) like in a := [] # empty list X while push(a, read()) X X pull <- -------------------- <- push X | LIST | X put -> -------------------- -> pop, get X XQuite important to realize is that Icon uses pointer semantics Xfor structures. This will say that a:=list(1000000) result in a Xpointer 'a'. What does b:=a mean? XSome programming languages copy the content of structures. In Icon Xit doesn't care what the value is, it copies the pointer. But Xalso you can do interesting things like a[2]:=a X XIf you read papers in the Police State of Programming, you find: X pointers are harmful. X XThe reason that we choose for pointer semantics is that in a Xtypeless language you are forced to it. Motivation was: Xwanting to have lists of lists, sets of sets, etc. X XBut it happens to be also efficient, although that was not the Xreason. There is procedure called 'copy' what will it do for you. X XTrees and graphs can really represented isomorph. There is an XIcon program library which has some procedures to make printable Xrepresentation of structures in Icon. Ths is done quite primitive. X XThere is no facility to make pictures of this yet. Somebody wants Xto do that? X X end of course.9-10 END_OF_icon/course/course09.10 if test 4321 -ne `wc -c icon/solution/sample.02 <<'END_OF_icon/solution/sample.02' X# Extend your solution to include tables, sets, and record X# types. You should handle structures that point to structures, but you X# need not handle loops. You can continue to ignore "difficult" X# characters in strings and csets. You should plan to make corrections X# that may show up as a result of the grading of your original solution. X# You also may wish to modify your previous solution to take advantage X# of generators. The coding scheme is the same as before, with the X# following additions: Sets are handled as lists by sorting them into X# lists before encoding. Tables are handled similarly, with the default X# value is kept as the first encoded value. For records, the record X# type is also kept as the first encoded value. Note that when records X# are reconstructed, a recored with no specified (i.e., null-valued) X# fields is constructed using the string invocation extension in Version X# 5.10. The fields are then filled in using positional access. X Xlink "/usr/ralph/main" X Xprocedure code(x) X if match("record",image(x)) then return "R" X if type(x) == ("set" | "co-expression") X then return map(type(x)[1],&lcase,&ucase) X else return type(x)[1] Xend X Xprocedure decode(s) X local p X every p := pair(s) do X suspend case p[1] of { X "i": integer(p[2]) X "s": p[2] X "c": cset(p[2]) X "r": real(p[2]) X "n": &null X "l": delist(p[2]) X "t": detable(p[2]) X "S": deset(p[2]) X "R": derecord(p[2]) X default: stop("unexpected type in decode: ",p[1]) Xend X Xprocedure delist(s) X local a X a := [] X every put(a,decode(s)) X return a Xend X Xprocedure derecord(s) X local a,z,i X a := [] X every put(a,decode(s)) X z := a[1]() # string invocation to create record X every i:=1 to *(a[2]) do # fill in the fields X z[i] := a[2][i] X return z Xend X Xprocedure deset(s) X return set(decode(s)) Xend X Xprocedure detable(s) X local a,t,i X a := [] X every put(a,decode(s)) X t := table(a[1]) # first value is default for table X a := a[2] X every i:=1 to *a-1 by 2 do X t[a[i]] := a[i+1] X return t Xend X Xprocedure encode(x) X local s,T X return case T := code(x) of { X "n": "0n" X !"risc": { X s := string(x) X *s || T || s X } X "l": enlist(x) X "S": enset(x) X "t": entable(x) X "R": enrecord(x) X default: stop("unsupported type in encode ",image(x)) X } Xend X Xprocedure enlist(a) X local s X s := "" X every s ||:= encode(!a) X return *s || "l" || a Xend X Xprocedure enrecord(x) X local s1,s2,a X s1 := encode(type(x)) # first value is record type X a := [] X every put(a,!x) X s2 := enlist(a) X return (*s1 + *s2) || "R" || s1 || s2 Xend X Xprocedure enset(S) X local s X a := enlist(sort(S)) X return *s || "S" || s Xend X Xprocedure entable(t) X local a,s1,s2 X a := sort(t,3) X s1 := encode(t[[]]) # default value X s2 := enlist(a) X return (*s1 + *s2) || "t" || s1 || s2 Xend X Xprocedure pair(s) X local i,j,k X j := 1 X while i := many('0123456789',s,j) do { X k := integer(s[j:i]) X suspend [s[i],s[i+1 +: k]] X j := i + k + 1 X } Xend X X end-of-solution 5 X# The coding scheme is the same as before, with the following additions: X# Sets are handled as lists by sorting them into lists before X# encoding. Tables are handled similarly, with the default value X# is kept as the first encoded value. For records, the X# record type is also kept as the first encoded value. X# Note that when records are reconstructed, a recored with no specified X# (i.e., null-valued) fields is constructed using the string invocation X# extension in Version 5.10. The fields are then filled in using positional X# access. X Xlink "/usr/ralph/main" X Xprocedure code(x) X if match("record",image(x)) then return "R" X if type(x) == ("set" | "co-expression") X then return map(type(x)[1],&lcase,&ucase) X else return type(x)[1] Xend X Xprocedure decode(s) X local p X every p := pair(s) do X suspend case p[1] of { X "i": integer(p[2]) X "s": p[2] X "c": cset(p[2]) X "r": real(p[2]) X "n": &null X "l": delist(p[2]) X "t": detable(p[2]) X "S": deset(p[2]) X "R": derecord(p[2]) X default: stop("unexpected type in decode: ",p[1]) Xend X Xprocedure delist(s) X local a X a := [] X every put(a,decode(s)) X return a Xend X Xprocedure derecord(s) X local a,z,i X a := [] X every put(a,decode(s)) X z := a[1]() # string invocation to create record X every i:=1 to *(a[2]) do # fill in the fields X z[i] := a[2][i] X return z Xend X Xprocedure deset(s) X return set(decode(s)) Xend X Xprocedure detable(s) X local a,t,i X a := [] X every put(a,decode(s)) X t := table(a[1]) # first value is default for table X a := a[2] X every i:=1 to *a-1 by 2 do X t[a[i]] := a[i+1] X return t Xend X Xprocedure encode(x) X local s,T X return case T := code(x) of { X "n": "0n" X !"risc": { X s := string(x) X *s || T || s X } X "l": enlist(x) X "S": enset(x) X "t": entable(x) X "R": enrecord(x) X default: stop("unsupported type in encode ",image(x)) X } Xend X Xprocedure enlist(a) X local s X s := "" X every s ||:= encode(!a) X return *s || "l" || a Xend X Xprocedure enrecord(x) X local s1,s2,a X s1 := encode(type(x)) # first value is record type X a := [] X every put(a,!x) X s2 := enlist(a) X return (*s1 + *s2) || "R" || s1 || s2 Xend X Xprocedure enset(S) X local s X a := enlist(sort(S)) X return *s || "S" || s Xend X Xprocedure entable(t) X local a,s1,s2 X a := sort(t,3) X s1 := encode(t[[]]) # default value X s2 := enlist(a) X return (*s1 + *s2) || "t" || s1 || s2 Xend X Xprocedure pair(s) X local i,j,k X j := 1 X while i := many('0123456789',s,j) do { X k := integer(s[j:i]) X suspend [s[i],s[i+1 +: k]] X j := i + k + 1 X } Xend X X end-of-solution 5 END_OF_icon/solution/sample.02 if test 6062 -ne `wc -c icon/solution/sample.icn <<'END_OF_icon/solution/sample.icn' X# Devise a scheme for encoding the various types of data in Icon as X# strings. Write a procedure encode(x) that encodes the value of x as a X# string and a function decode(s) that produces value encoded in s. In X# general X# X# x := decode(encode(y)) X# X# should result in x being assigned a value that is the same as the X# value of y, except that for structures, the values should be X# "similar", not identical. Thus, in X# X# a := [] X# b := decode(encode(a)) X# X# the value assigned to b should be an empty list, but not the X# empty list that is the value of a. X# X# This is the first phase of this problem. For this first phase, X# you should handle the null value, integers, real numbers, X# strings, csets, and lists. You need not to handle strings and X# csets that contain characters that would require escape X# conventions for their literal representation. You need not handle X# lists whose values are lists, and so on, but plan ahead. X# X# Do not provide a main procedure. Instead, include the following X# declaration at the beginning of your program: X# X# link "/usr/ralph/main" X# X# This will incorporate a main procedure that tests your encode and X# decode procedures. (This main procedure will remain the same X# until the assignment is due, unless you are informed otherwise, X# but will be changed when your assignment is run by the daemon.) X# X# A value is encoded as a string consisting of three parts: X# giving the length of the encoded value itself, a character code for X# the type of the value, and the encoded value. Examples: X# X# X# 1 1i1 X# "xyz" 3sxyz X# 'abc' 3cabc X# X# X# List are encoded similarly, except the encoded values of the elements X# are simply concatenated and the total size is given at the beginning. X# Example: X# X# [1,"xyz",'abc'] 13l1i13sxyz3cabc X# X X# Extend your solution to include tables, sets, and record X# types. You should handle structures that point to structures, but you X# need not handle loops. You can continue to ignore "difficult" X# characters in strings and csets. You should plan to make corrections X# that may show up as a result of the grading of your original solution. X# You also may wish to modify your previous solution to take advantage X# of generators. The coding scheme is the same as before, with the X# following additions: Sets are handled as lists by sorting them into X# lists before encoding. Tables are handled similarly, with the default X# value is kept as the first encoded value. For records, the record X# type is also kept as the first encoded value. Note that when records X# are reconstructed, a recored with no specified (i.e., null-valued) X# fields is constructed using the string invocation extension in Version X# 5.10. The fields are then filled in using positional access. X Xlink "/usr/ralph/main" X Xprocedure code(x) X if match("record",image(x)) then return "R" X if type(x) == ("set" | "co-expression") X then return map(type(x)[1],&lcase,&ucase) X else return type(x)[1] Xend X Xprocedure decode(s) X local p X every p := pair(s) do X suspend case p[1] of { X "i": integer(p[2]) X "s": p[2] X "c": cset(p[2]) X "r": real(p[2]) X "n": &null X "l": delist(p[2]) X "t": detable(p[2]) X "S": deset(p[2]) X "R": derecord(p[2]) X default: stop("unexpected type in decode: ",p[1]) X } Xend X Xprocedure delist(s) X local a X a := [] X every put(a,decode(s)) X return a Xend X Xprocedure derecord(s) X local a,z,i X a := [] X every put(a,decode(s)) X z := a[1]() # string invocation to create record X every i:=1 to *(a[2]) do # fill in the fields X z[i] := a[2][i] X return z Xend X Xprocedure deset(s) X return set(decode(s)) Xend X Xprocedure detable(s) X local a,t,i X a := [] X every put(a,decode(s)) X t := table(a[1]) # first value is default for table X a := a[2] X every i:=1 to *a-1 by 2 do X t[a[i]] := a[i+1] X return t Xend X Xprocedure encode(x) X local s,T X return case T := code(x) of { X "n": "0n" X !"risc": { X s := string(x) X *s || T || s X } X "l": enlist(x) X "S": enset(x) X "t": entable(x) X "R": enrecord(x) X default: stop("unsupported type in encode ",image(x)) X } Xend X Xprocedure enlist(a) X local s X s := "" X every s ||:= encode(!a) X return *s || "l" || a Xend X Xprocedure enrecord(x) X local s1,s2,a X s1 := encode(type(x)) # first value is record type X a := [] X every put(a,!x) X s2 := enlist(a) X return (*s1 + *s2) || "R" || s1 || s2 Xend X Xprocedure enset(S) X local s X a := enlist(sort(S)) X return *s || "S" || s Xend X Xprocedure entable(t) X local a,s1,s2 X a := sort(t,3) X s1 := encode(t[[]]) # default value X s2 := enlist(a) X return (*s1 + *s2) || "t" || s1 || s2 Xend X Xprocedure pair(s) X local i,j,k X j := 1 X while i := many('0123456789',s,j) do { X k := integer(s[j:i]) X suspend [s[i],s[i+1 +: k]] X j := i + k + 1 X } Xend END_OF_icon/solution/sample.icn if test 5019 -ne `wc -c icon/solution/solution.07 <<'END_OF_icon/solution/solution.07' X C.Sc. 550 - String and List Processing X X Suggested Solutions to Homework Assignment 7 X X X1. odd.icn X X procedure odd(a) X while e1 := @a[1] do { X suspend e1 X @a[1] | break X } X end X X X2, coscan.icn X X link "/usr/ralph/comain" X X procedure Scan(a) # Scan{e1,e2} X local e1, e2, outersubj, innersubj, outerpos, innerpos X X outersubj := &subject # save outer environment X outerpos := &pos X while e1 := @a[1] do { # iterate over results of first argument X s := string(e1) | stop( X "Run-time error 103\nstring expected\noffending value:", image(e1)) X &subject := s # set up the new environment X &pos := 1 X while e2 := @a[2] do { # iterate over results of second argument X innersubj := &subject # save inner environment X innerpos := &pos X &subject := outersubj # restore outer environment X &pos := outerpos X suspend e2 # produce result X &subject := innersubj # restore inner environment X &pos := innerpos X } X a[2] := ^a[2] # refresh second argument X &subject := outersubj # restore outer environment X &pos := outerpos X } X end X X procedure main() X a := ["Hello", "world", "!"] X every write(Scan{!a, move(1 to 10) | tab(0 to -5 by -1)}) X every snap("level zero") X &subject := "ABCDEF" X &pos := 4 X snap(1) & Scan{"abcdef", tab(upto(&lcase)) & snap(2)} & snap(3) & &fail X every snap("the end") X end X X procedure snap(i) X write("entering ", i) X write(&subject = ", &subject) X write(&pos = ", &pos) X suspend X write("resuming ", i) X write("&subject = ", &subject) X write("&pos = ", &pos) X fail X end X XThe correct output for this test is: X X H X He X Hel X Hell X Hello X Hello X Hell X Hel X He X H X X w X wo X wor X worl X world X world X worl X wor X wo X w X X ! X ! X X entering level zero X &subject = X &pos = 1 X resuming level zero X &subject = X &pos = 1 X entering 1 X &subject = ABCDEF X &pos = 4 X enetring 2 X &subject = abcdef X &pos = 1 X entering 3 X &subject = ABCDEF X &pos = 4 X resuming 3 X &subject = ABCDEF X &pos = 4 X resuming 2 X &subject = abcdef X &pos = 1 X entering 2 X &subject = abcdef X &pos = 1 X entering 3 X &subject = ABCDEF X &pos = 4 X resuming 3 X &subject = ABCDEF X &pos = 4 X resuming 2 X &subject = abcdef X &pos = 2 X entering 2 X &subject = abcdef X &pos = 3 X entering 3 X &subject = ABCDEF X &pos = 4 X resuming 3 X &subject = ABCDEF X &pos = 4 X resuming 2 X &subject = abcdef X &pos = 3 X entering 2 X &subject = abcdef X &pos = 4 X entering 3 X &subject = ABCDEF X &pos = 4 X resuming 3 X &subject = ABCDEF X &pos = 4 X resuming 2 X &subject = abcdef X &pos = 4 X entering 2 X &subject = abcdef X &pos = 5 X entering 3 X &subject = ABCDEF X &pos = 4 X resuming 3 X &subject = ABCDEF X &pos = 4 X resuming 2 X &subject = abcdef X &pos = 5 X entering 2 X &subject = abcdef X &pos = 6 X entering 3 X &subject = ABCDEF X &pos = 4 X resuming 3 X &subject = ABCDEF X &pos = 4 X resuming 2 X &subject = abcdef X &pos = 6 X resuming 1 X &subject = ABCDEF X &pos = 4 X entering the end X &subject = ABCDEF X &pos = 4 X resuming the end X &subject = ABCDEF X &pos = 4 X X end-of-solution-assignment-9 END_OF_icon/solution/solution.07 if test 3679 -ne `wc -c References: <481@atcmpe.atcmp.nl> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh icon/course/course09.05 <<'END_OF_icon/course/course09.05' XHOMEWORK for next Tuesday: Read Chapter V on Structures. X XRalph started out with talking about character sets and defending Xhis choice for 8-bit character code. X XCHARACTER SETS: X6-bits BCD, CDC Display code X7-bits ASCII X8-bits EBCDIC X9-bits GE X XMore bits per character may blow up wordsize tables which are Xexplained later on. The DEC-10 has the possibilty to specify the Xbyte length. More than 8-bit character codes are mostly be used Xin linguistics and typesetting. XThere are also methods of encoding the output stream if you need Xmore than 256 characters. Eg. for driving laser printers. X XEBCDIC has the advances that the ordening is more logical in the Xsense that the value of "a" is "smaller" than "A" and "0" but Xthere gaps in the sequence X 129 193 XEBCDIC a ... i -gap- j ... r -gap- s ... z -gap A ... etc X XThese gaps makes it quite bizarre. ASCII is at least contiguous. X X 48 65 97 XASCII 0 ... 9 A ... Z a ... z X XIn Icon Version 5 the value of the characters is standarized. So Xno matter what the inside character set is in the computer the Xvalue of data in Icon is always in ASCII values. Even on an XEBCDIC machine. X XC uses the {null} character as an end of string marker. In Icon Xstrings are stored as a string AND a length. So storage goes Xlike: X -6-5-4-3-2-1 0 X 1 2 3 4 5 6 7 Xs := "abc" -| a b c x y z X(lgt = 3) | ^ ^ |-- t := s1[2:7] (lgt = 5) X |-----------| |----------| X | |---- s1 := s || "xyz" (lgt = 6) X |-------------| X XSo Icon stores strings packed. X X s[1] := "r" or s1 := "r" || s1[2:0] XThis will construct a new string at the end of the string pool. XIt is not plausible efficient to look for an already available Xpattern in the string pool. X XSTRINGS: XConcatenation s3 := s1 || s2 XAnalytic s[i:j] X XA rich set of functions is available X Xright(s1,i,s2) | string| s2 is the filler string Xleft(s1,i,s2) |string | leaving out will be a blank Xcenter(s1,i,s2) | string | X XYou will always get a string of length i. s1 will be cut off, if Xi is shorter than the length of the string. (No fun to implement this!) X Xrepl(s,i) replicate a string Xreverse(s) reverse strings, its use is questionable Xtrim(s,c) remove blanks from card images X XAn real interesting function is 'map'. X Xmap(s1,s2,s3) character mapping function Xs1 := "abcabcca" Xs2 := "a+c" Xs3 := "z-z" Xmap(s1,s2,s3) will then result in "zbzzbzzz" X Xmap(s,"aeiouAEIOU","++++++++++") replaces all vowels by "+" X XThe following program will highlight all the vowels in a string s: X X trim(map(s,&cset || &vowel, repl(" ",*&cset) || repl("|", *&vowel))) Xso X s := "boy this is something" X write(s) X write(trim(map(s...))) X Xwill result in X X boy this is something X || | | | | | X Xremark that it is only one statement doing this! The Ximplementation of this is quite interesting. It is done by Xcharacter mapping tables. X XSo in a table of 256 characters the "a" is 97 ascii. This becomes X"|" which is value 124. Etc. X XThis table is cached, if you take it out the loop (as in map), it Xwill not being rebuild. It is fast, much more faster than picking Xup a character, change it value, etc. X XThis is not just a weird function, it was motivated because 'map' Xwas hardwired in the IBM370 models. X X end of course.9-5 END_OF_icon/course/course09.05 if test 3315 -ne `wc -c icon/course/course09.19 <<'END_OF_icon/course/course09.19' X 19 Sept 1985 X ------------ X XASSIGNMENT: Read up to chapter 10 X XImplementations of Icon X======================= X1. Icon is supported by the NSF, so public domain X2. Primary implemented on the UNIX Operating System X VAX, PDP11, Ridge-32 (RISC machine), SUN, AT&T 3B20, IBM PC (PC/IX), X UNIX-PC (AT&T 7300), various Motorola machines (Integrated Solutions) X3. others: VAX/VMS, MSDOS (has a bug in co-expressions) X Xprocedures X========== X p := write X XProgramming example as in passing on an actual parameter as procedure: X X procedure foo(p,s) X p(s) X end X Xreturning X--------- X return [ expr ] -> return result or fails if 'expr' fails X fail -> does not return previous, fails X flowing off end -> same as fail X Xwarning X------- X syntactic shortcoming: Do no put anything behind 'return'. X Xrecursion X========= XLater on we will show some good examples on text. So for the time Xwe use the boring numerical ones: X X procedure fib(i) X if i = 1 then return 1 X if i = 2 then return 2 X return fib(i-1) + fib(i-2) X end X XThe only reason that this works is because 'fib' is a global Xvariable. So placing X local fib Xin the body is disastrous (returns {null}) XAcceptable would be X local gib; gib := fib X ... X return gib(i-1) + gib(i+1) X XOrder of evaluation X------------------- X Expr ( expr1, expr2, expr3, ..., exprn) X n+1 1 2 3 n X X'Expr' will fail if any of the others fail. X X Too few parameters -> null values supplied X Too many -> discards X XArguments are not dereferenced until ALL are evaluated. XThat means if you do things what you are not supposed to like in X X trim(s,c,if i>j then trim := &null) X X write(s,s:="x") -> result "xx" no matter what X Xdereferencing X============= XThe dot before a variable will always cause it to dereference, Xright to left assignment will always dererence. If you don't Xtrust anything you could always use X .c instead of c X X procedure calc(...) X local i X ... X return i # dereferences X end X XCan you say: X X calc(s) := 3 X XIf the 'i' was global instead of local than X calc(s) := 3 is the same as i := 3 X XWe could dereference everything but there is no need for. XIt is not really a problem because it only can give a problem in X procedure := variable X X procedure awful(s,i) X local s X return s[i] X end X XSo awful(x,3) := "xxx" would suggest s[i] := "xxx". XWrong! Error message: assignment which is not a variable. X XThis is a language design issue, not part of this course. X X end-of-course.9-19 END_OF_icon/course/course09.19 if test 2469 -ne `wc -c icon/course/course10.01 <<'END_OF_icon/course/course10.01' X C.Sc. 550 - String and List Processing X 10/1/85 X XToday we are talking on the concept of GENERATORS. X Xgenerators X---------- X XTogether with `string-scanning' and `co-expressions' belong X`generators' to the extension of the `basics' of Icon. XGenerators are quite important and we will spend quite a bit of Xtime on it. Why? Because I like it. (Griswold) X XConsider s1:="Here are later answers" X | | | X 2 13 20 X X every i := find("er", s1) do write(i) X XThis results in a zero length result sequence. XIt fails only if it produces no result at all. X X 5 + find("er", s1) -> {7, 18, 25} X XThe do clause is optional, another way of writing is every write("er",s1)) X XThis one is a better way of writing it and produces more efficient code. XIf you compare X every write(find("er",s1)) outcome does not have a result X write(every find("er",s1)) outcome will fail (so not very helpful) X Xa break is permitted like in X every e1 do { ... break ... } X XThe expression X while i:=find("er",s1) do write(i) Xis not a generator and will produces only 2's X Xgoal-directed evaluation (GDE) X------------------------ X if find("er",s1) > 10 then e1 else e2 X XThe evaluation tries to find a position in s1 > 10. So GDE goes on till it Xfinds the first result. In the previous example of s1:="Here are later answers" Xthe result of the if clause is X {2, 13 20} -> 13 and is > 10 X XExample: X if 18 > find("er",s1) > 10 then e2 else e3 X XYou find this through the whole language. PROLOG has some of it. X X every write(find(s1,s2) = find(s3,s4)) X Xgives all the possible results. 'S' stands for 'result-sequence' X X s1 := "Here are later answers" X s2 := "Here are later results to read" X X1) S(find("er",s1)) = {2,13,20} X2) S(find("re",s2)) = {3,7,16,27} X X S(find("er",s1)) + find("re",s2)) X Xevaluation: In all operations there is left to right evaluation Xresumption: Last in, first out. All resumption are LIFO X X 1) + 2) = {5,9,18,29,16,20,29,40,23,27,36,47} X 2 + 3 X 2 + 7 X 2 + 16 If the operator was > instead of + X 2 + 27 the result sequence is X 13 + 3 {3,7,3,7,16} X . X . The result sequence is {} X . if the operator is = X 20 + 27 X XOther generators: X X 1 to 10 -> {1,2,3,4,5,6,7,8,9,10} X Xwhat does every i:=1 to 10 do f(i) X XIn Icon this is easier composed than in Algol like languages Xeasier written as X every if(1 to 10) X XThis takes some getting used to. This is a conceptual change from other Xlanguages. You have to see how to use this. It is hard to brak from C like Xprejustice. X XThis is the point in the the course that you can get lost. XSo ask QUESTIONS if you have any. X X end-of-course 10-1-85 END_OF_icon/course/course10.01 if test 2681 -ne `wc -c icon/course/course10.17 <<'END_OF_icon/course/course10.17' X C.Sc. 550 - String and List Processing X X 85/10/17 X XDiscussion Midterm Examination XHanding out homework #6 XRead Chapt 13 co-expressions X XString Scanning X=============== X XFinishing up this subject today. This is together with 'generator' and 'co- Xexpression' one of the most important features of Icon. X XString scanning, or pattern matching, was the reason behind Snobol4. Pattern Xand pattern matching in Snobol motivated Icon. X XMotivation: get a higher level of string scanning, especially for analysis Xdecoding information (and to less extent for synthesis). XAutomatically handling of string position, etc. Xone string - subject Xone place (focus) for attention - position XOperator is ? like in s ? expr X XExample: X while line := read() do { # low level X i := 1 # programming X while j := upto(wchar,line,i) do { X i := many(wchar,line,j) X words[line[i:j]] +:= 1 X } X } X X s ? expr tab(i) sets position to i Xline ? expr move(i) increment position by i X Xthese are called -> matching functions X X upto(wchar) is then upto(wchar,"subject","position") X XSo X while line := read() do { X line ? while tab(upto(wchar)) { X words[tab(many(wchar))] +:= 1 X } X } X XSo you don't have to mention i,j,line etc. This is 2/3 of the story of string Xscanning. This way of programming is very difficult programming, so I warn you Xthat you get frustated about it. But it pays off! X XIn general the outcome of s?expr X is the outcome of expr X XThere is also an augentation ?: operator. Take care because of precedence. XLike X s ? expr1 & expr2 groups as (s ? expr1) & expr2 XSo use braces as in X s ? (expr1 & expr2) X Xexpr1 ? expr2 both expressions can be generators. X X L(S(expr1)) X S(expr1 ? expr2) = S(expr2) X X ^ X |__ this is a control structure and not an operation X X ( operators + - * ... X operation < evaluation always from left to right X ( functions: to by X XString scanning is a control structure. You evaluate expr1 to set the subject Xand the position and then you do expr2. So before the operation is done before Xall the evaluation is done. X X &subject is used for non-Icon matching procedures X &pos X X &subject := read() side effect &pos := 1 X Xstacking subjects X X if s ? expr X XThe subject is restored afterwards as it was before. The environment saving Xand restoring is dynamic. So X X every (s ? expr1) ? expr2 X Xdoes what you expect it to do. X Xdata-backtracking X================= X X tab(i) & move(17) if move fails it resumes as before tab(i). X XThe assignment of the position is implicit here X X expr1 | if expr1 fails it restores the subject so X expr2 | you can count on it by going in to expr2 X expr3 etc. X XCurious effects: X X while tab(upto(wchar)) do X suspend tab(many(wchar)) X XSo this is not a generator because this is a programming pitfall!! XHow do you prefend this? One way is X X while tab(upto(wchar)) do { X word := tab(many(wchar)) X suspend word X } Xanother way, replace X suspend tab(many(wchar)) Xby X suspend tab(many(wchar)) \ 1 X XTHIS PITFALL IS GROSS..! X END_OF_icon/course/course10.17 if test 3283 -ne `wc -c icon/course/course10.22 <<'END_OF_icon/course/course10.22' X C.Sc. 550 - String and List Processing X X 85/10/22 X X XEvaluation order and Resuming X X e1 ? e2 -> Escan ( Bscan (e1), e2 ) X 4 2 1 3 X XIf you can see this without looking at the code, you understand what is going Xon. X X record ScanState(subject,pos) X X procedure Bscan(e1) X . X . X CenterState := ScanState(&subject,&pos) X &subject := s X &pos := 1 X suspend OuterState # 1 and 2 done X &subject := OuterState.subject X &pos := OuterState.pos X end X X procedure Escan(OuterState,e2) X local InnerState X InnerState := ScanState(&subject,&pos) X &subject := OuterState.subject X &pos := OuterState.pos X suspend e2 # at this point, the whole thing is X # succeeded. Itonly resumes unless X# another result is requested. X &subject := InnerState.subj X &pos := InnerState.pos X fail X end X XLater on if we get further on string scanning (this is only the surface) we Xwill do more on this. We have some programs to display the state of scanning Xon a SUN. The book is not really indepth on this. X X e0 & ( e1 ? e2 ) & e3 Xouterstate outerstate X innerstate X XA practical example: f("abc" ? e1) X XThe trick to all of this, write these procedures as reversable arguments. XThis mechanism is a rather general way and this can be part of a database, Xetc. X XCo-expressions X============== X XThey were added later on to solve a difficulty. X e1 +o e2 gives a kind of cross product evaluation, e1 will only go to next Xone if all of e2 is evaluated. This is built in to Icon and does mean that you Xcannot do certain things. See intro Chapter 13. X X S(!&lcase) = {"a", "b", ..., "z"} X e1 := create !&lcase X e2 := create !&ucase X X So first time write(@e1) -> "a" X second time write(@e1) -> "b" X write(@e2) -> "A" X then X while write(@e1, @e2) X -> cB X dC X . X . X zY X X this fails and stops the loop (and no core dump anymore in Version 5.10!!!) X Xwhat is this good for? X label generating in assembly/compiler X labgen := create "L" || (1 to 1000) X . X . X @labgen X Xif you want to reset the co-expression X X e1 := ^e1 # refresh, uses a different copy X XExample X------- X procedure Labgengen(s,i,j) X return creat (s || (i to j + 100)) X end X X s,i,j are local X but it returns a dat-object X X X := labgengen("L",1000,1003) X X what actually happens is that co-expression make copies of all the local Xvariables at the time the create is done. So, copies s,i, and j. X XEvery co-expression has its own stack X X end-of-course-10.22 END_OF_icon/course/course10.22 if test 2874 -ne `wc -c icon/homework/assign.mid <<'END_OF_icon/homework/assign.mid' X Name: ___________________ X X X Midterm 1 X XGeneral Instructions: XThis is a closed book examination. Show all your work. Use the backs of pages Xif necessary, but be sure to mark such work clearly. Cross out any work you do Xnot want to be considered in grading. If you can not do all of a problem, do Xwhat you can and indicate what you have in mind for the remaining portion - Xpartial credit will be given. If you make an assumption in interpreting a Xproblem, state that assumption. If you do not recall sopme detail of Icon, do Xthe best you can and explain what you have in mind. X XNote: Style counts. In the case of programming problems, produce the best Xprogram you can. X X X1. (16 points) Write a program that counts the number of times each different Xcharactert occurs in the input file and writes out the results. For example, Xfor the input file X X Of the bells, bells, bells, bells, X Bells, bells, bells- X Xthe output might look like X X : 7 X ,: 6 X -: 1 X B: 1 X O: 1 X b: 6 X e: 8 X f: 1 X h: 1 X l: 14 X s: 7 X t: 1 X X X2. (25 points) After evaluation of X X a := [5,10] X Xthe value of a can be diagrammed as follows X -------- X a ----->| 5 | X |------| X | 10 | X -------- X XAssuming a has this value originally, diagram the value of a, b, and c as they Xare after completion of the evaluation of the following epression: X X push(a,15) X b := a X put(b,20) X c := [a,30] X c[2] := b X b[2] := c X X X3. (24 points) Show the result sequences for the following expressions. If Xa result is infinite, indicate that by ellipses. For example, the result Xsequence for |1 should be shown as {1,1,1,...}. X X (1) (1 to 3) + 4 X X (2) (1|2) to (3|4) X X (3) (2 to 4) - (1 to 3) X X (4) (|(1 to 3)) \ 4 X X (5) (1 to 3) || (1 to 3) X X (6) (|(1 to 3)) | (|(2 to 4)) X X (7) (|(1 to 5)) \ (3|0) X X (8) (1 to 20) = (5 to 15) X X X4. (15 points) Write a procedure that 'generates' the factorials of the Xpositive integers in increasing order: 1, 2, 6, 24, 120, ... X X X5. (20 points) Using the following notation for result sequences: X X S(expr) the result sequence for expr X X L(expr) the length of the result sequence for expr X X S1 +o S2 the concatenation of the result seqeunces S1 and S2 X X /o the empty result sequence X X X (a) Give the result sequence for X X (expr1 & expr2) | expr3 X Xin terms of the result sequences for expr1, expr2, and expr3. Assume that Xexpr1, expr2, and expr3 are self-contained. X X (b) Under what circumstances is the result sequence for the expression Xabove the same as the result sequence for X X if expr1 then expr2 else expr3 X X end-of-Midterm-1 END_OF_icon/homework/assign.mid if test 2828 -ne `wc -c icon/solution/solution.02 <<'END_OF_icon/solution/solution.02' X X XSuggested Solutions to Homework Assignment 2 X X1. concord.icn X Xprocedure main() X letters := &lcase ++ &ucase X words := table("") X maxword := lineno := 0 X while line := read() do { X lineno +:= 1 X write(right(lineno,6)," ",line) X line := map(line) # fold to lowercase X i := 1 X while j := upto(letters,line,i) do { X i := many(letters,line,j) X word := line[j:i] X if *word < 3 then next # skip short words X maxword <:= *word # keep track of longes word X # if it's a new word, start set X if *words[word] = 0 then words[word] := set([lineno]) X else insert(words[word],lineno) # else add line number X } X } X write() X wordlist := sort(words,3) # sort by words X i := 1 X while word := wordlist[i] do { X lines := "" # build up line numbers X numbers := sort(wordlist[i+1]) X while lines ||:= get(numbers) || "," X write(left(word,maxword+2), ": ",lines[2]) X i +:= 2 X } Xend X X X2. rational.icn X Xrecord rational(numer,denom) X Xprocedure main() X test() # put test procedure elsewhere Xend X Xprocedure strrat(s) X i := find("/",s) X return reduce(s[1:i],s[i+1:0]) Xend X Xprocedure ratstr(r) X return r.numer || "/" || r.denom Xend X Xprocedure reduce(numer,denom) X if denom = 0 then stop("zero denominator") X if numer = 0 then return rational(0,1) X if denom < 0 then { X numer := -numer X denom := -denom X } X divisor := gcd(abs(numer),denom) X return rational(numer/divisor,denom/divisor) Xend X Xprocedure gcd(i,j) X repeat { X rem := i % j X if rem = 0 then return j X i := j X j := rem X } Xend X Xprocedure mpyrat(r1,r2) X return reduce(r1.numer * r2.numer, r1.denom * r2.denom) Xend X Xprocedure addrat(r1,r2) X return reduce(r1.numer * r2.denom + r2.numer * r1.denom, X r1.denom * r2.denom) Xend X Xprocedure test() X ratlist := [] X nlist := [0,1,-1036,-5] X dlist := [1,13,-144] X write("testing conversion") X i := 1 X while numer := nlist[i] do { X i +:= 1 X j := 1 X while denom := dlist[j] do { X j +:= 1 X s := numer || "/" || denom X r := strrat(s) X write(s," = ",ratstr(r)) X put(ratlist,strrat(s)) X } X } X write() X write("testing arithmetic:") X i := 1 X while r1 := ratlist[i] do { X i +:= 1 X j := 1 X while r2 := ratlist[j] do { X j +:= 1 X write("(",ratstr(r1),")+(",ratstr(r2),")=",ratstr(addrat(r1,r2))) X write("(",ratstr(r1),")*(",ratstr(r2),")=",ratstr(mpyrat(r1,r2))) X } X } X write("checking zero denominator") X strrat("13/0") Xend END_OF_icon/solution/solution.02 if test 2363 -ne `wc -c icon/solution/solution.04 <<'END_OF_icon/solution/solution.04' X Suggested Solutions to Homework Assignment 4 X X1. balexp.icn X X procedure main() X while line := read() do { X bar := repl(" ",*line) X every bar[bal('+-*',,,line)] := "|" X write(line,"\n",trim(bar)) X } X end X X X2. code.icn X X # A value is encoded as a string consisting of three parts: X # giving the length of the encoded value itself, a character code for X # the type of the value, and the encoded value. Examples: X # X # X # 1 1i1 X # "xyz" 3sxyz X # 'abc' 3cabc X # X # X # List are encoded similarly, except the encoded values of the elements X # are simply concatenated and the total size is given at the beginning. X # Example: X # X # [1,"xyz",'abc'] 13l1i13sxyz3cabc X # X X link "/usr/ralph/main" X X procedure decode(s) # generate pair of form [code,string] X every p := pair(s) do X suspend case p[1] of { X "i": integer(p[2]) X "a": p[2] X "c": cset(p[2]) X "r": real(p[2]) X "n": &null X "l": delist(p[2]) X default: stop("unexpected type in decode: ",x) X } X end X X procedure delist(s) X a := [] X every put(a,decode(s)) X return a X end X X procedure encode(x) X return case T := code(x) of { X "n": "0n" X !"risc": { # reals, integers, strings, and csets are X #N6 := string(x) # encoded the same way X *s || T || s X } X "l": enlist(x) X default: stop("unsupported type: ",image(x)) X } X end X X procedure enlist(a) X s := "" X every s ||:= encode(!a) # concatenate the encoded elements X return *s || "l" || s X end X X procedure pair(s) # parse a value and generate pairs X # of the form [code,string] X local i,j,k X j := 1 X while i := many('0123456789',s,j) do { X k := integer(s[j:i]) | stop("size coding error") X suspend [s[i],s[i+1 +: k]] X j := i + k + 1 X } X end X X procedure code(x) # plan ahead; generate unique type code letters X if type(x) == "set" then return "S" X else return type(x)[1] X end X X # X # main program used for most tests X # X procedure main() X values := [&null,1,2.0,'abc',"abc"] X every write(image(decode(encode(!values)))) X s := encode(values) X write(s) X a := decode(s) X write(image(a),": ",image(values)) X every i:=1 to *a do X write(image(a[i]),": ",image(values[i])) X tmp := open("/tmp/codedata","w") | stop("cannot open tmp file") X s := string(&cset[20:0]) X t := encode(s) X write(tmp,t) X a := [1,2,3,4,"abc",'abc'] X b := encode(a) X write(tmp,b) X close(tmp) X tmp := open("/tmp/codedata") | stop("cannot reopen tmp file") X u := read(tmp) X if t ~== u then write("transmission of encoded string fails") X else v := decode(u) X if v ~== s then write("decoding of transmitted string failed") X c := read(tmp) | stop("eof reading tmp") X if b ~== c then write("transmission of encoded list failed") X d := decode(c) X every i:=1 to *a do X if a[i] ~=== d[i] then write("list element comparison failure for ", X i, " = ",image(a[i])) X system("rm -f /tmp/codedata") X end X X X end-of-solution 4 END_OF_icon/solution/solution.04 if test 3420 -ne `wc -c icon/solution/solution.05 <<'END_OF_icon/solution/solution.05' X Suggested Solutions to Homework Assignment 5 X X1. ranseq.icn X X procedure main() X every write(ranseq(100)) \ 50 X end X X procedure ranseq(i) X suspend ?|i X end X X X2. ranseql.icn X X procedure main() X every write(ranseql(100,35)) X end X X procedure ranseql(i,j) X suspend |(j ~= ?i) | j X end X X X3. code.icn X X # The coding scheme is the same as before, with the following additions: X # Sets are handled as lists by sorting them into lists before X # encoding. Tables are handled similarly, with the default value X # is kept as the first encoded value. For records, the X # record type is also kept as the first encoded value. X # Note that when records are reconstructed, a recored with no specified X # (i.e., null-valued) fields is constructed using the string invocation X # extension in Version 5.10. The fields are then filled in using positional X # access. X X link "/usr/ralph/main" X X procedure code(x) X if match("record",image(x)) then return "R" X if type(x) == ("set" | "co-expression") X then return map(type(x)[1],&lcase,&ucase) X else return type(x)[1] X end X X procedure decode(s) X local p X every p := pair(s) do X suspend case p[1] of { X "i": integer(p[2]) X "s": p[2] X "c": cset(p[2]) X "r": real(p[2]) X "n": &null X "l": delist(p[2]) X "t": detable(p[2]) X "S": deset(p[2]) X "R": derecord(p[2]) X default: stop("unexpected type in decode: ",p[1]) X end X X procedure delist(s) X local a X a := [] X every put(a,decode(s)) X return a X end X X procedure derecord(s) X local a,z,i X a := [] X every put(a,decode(s)) X z := a[1]() # string invocation to create record X every i:=1 to *(a[2]) do # fill in the fields X z[i] := a[2][i] X return z X end X X procedure deset(s) X return set(decode(s)) X end X X procedure detable(s) X local a,t,i X a := [] X every put(a,decode(s)) X t := table(a[1]) # first value is default for table X a := a[2] X every i:=1 to *a-1 by 2 do X t[a[i]] := a[i+1] X return t X end X X procedure encode(x) X local s,T X return case T := code(x) of { X "n": "0n" X !"risc": { X s := string(x) X *s || T || s X } X "l": enlist(x) X "S": enset(x) X "t": entable(x) X "R": enrecord(x) X default: stop("unsupported type in encode ",image(x)) X } X end X X procedure enlist(a) X local s X s := "" X every s ||:= encode(!a) X return *s || "l" || a X end X X procedure enrecord(x) X local s1,s2,a X s1 := encode(type(x)) # first value is record type X a := [] X every put(a,!x) X s2 := enlist(a) X return (*s1 + *s2) || "R" || s1 || s2 X end X X procedure enset(S) X local s X a := enlist(sort(S)) X return *s || "S" || s X end X X procedure entable(t) X local a,s1,s2 X a := sort(t,3) X s1 := encode(t[[]]) # default value X s2 := enlist(a) X return (*s1 + *s2) || "t" || s1 || s2 X end X X procedure pair(s) X local i,j,k X j := 1 X while i := many('0123456789',s,j) do { X k := integer(s[j:i]) X suspend [s[i],s[i+1 +: k]] X j := i + k + 1 X } X end X X end-of-solution 5 END_OF_icon/solution/solution.05 if test 3497 -ne `wc -c icon/solution/solution.09 <<'END_OF_icon/solution/solution.09' X C.Sc. 550 - String and List Processing X X Suggested Solutions to Homework Assignment 9 X X X1. recgen.icn X X procedure main() X system("rm -rf /tmp/ralph"); X system("mkdir /tmp/ralph"); X output := open("/tmp/ralph/recog.icn","w")|stop("cannot opem tmp file"); X input := open("/usr/ralph/recgen.gmr") | stop("sannot open input file"); X while line := read(input) do X if line ? { X nt := tab(any(&ucase)) & X ="::=" & X write(output, "procedure ", nt, "()") & X body := "" & { X every body ||:= altern(tab(0)) X write(output, " suspend(\n", body[1:-3]", "\n )\nend\n") X } X } then next X else if line ? (goal := tab(any(&ucase))) & pos(0) then { X write(output, "procedure main()") X write(output, " while writes(image(line := read())) do") X write(output, X " if line ? (",goal,"() & pos(0)) then write(\" accepted")") X write(output, " else write(\" rejected\")") X write(output, "end") X break X } else X stop("invalid input") X system("icont -s /tmp/ralph/recog.icn -x Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu In 1985 I could attend a graduate course in string and list processing by Ralph Griswold. In the spring of 1986 I put it on the net in Europe, with Ralphs permission of course. Let me do this again, it was an excellent course and this might give you some insight in the language. Especially if you want to teach it in your computer science class yourself. The language is great to get understanding in compiler building and parsing. The text is made available as is. gertjan@atcmp.nl #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh MANIFEST <<'END_OF_MANIFEST' X File Name Archive # Description X----------------------------------------------------------- X MANIFEST 1 This shipping list X icon 1 X icon/course 1 X icon/course/course08.27 1 X icon/course/course08.29 3 X icon/course/course09.03 3 X icon/course/course09.05 2 X icon/course/course09.10 3 X icon/course/course09.12 1 X icon/course/course09.17 1 X icon/course/course09.19 2 X icon/course/course09.23 1 X icon/course/course10.01 2 X icon/course/course10.03 1 X icon/course/course10.10 1 X icon/course/course10.17 2 X icon/course/course10.22 2 X icon/homework 1 X icon/homework/assign.03 1 X icon/homework/assign.04 1 X icon/homework/assign.05 1 X icon/homework/assign.06 1 X icon/homework/assign.08 1 X icon/homework/assign.09 1 X icon/homework/assign.10 1 X icon/homework/assign.mid 2 X icon/solution 1 X icon/solution/sample.02 3 X icon/solution/sample.icn 3 X icon/solution/solution.01 1 X icon/solution/solution.02 2 X icon/solution/solution.03 1 X icon/solution/solution.04 2 X icon/solution/solution.05 2 X icon/solution/solution.06 1 X icon/solution/solution.07 3 X icon/solution/solution.08 1 X icon/solution/solution.09 2 X icon/solution/solution.mid 1 END_OF_MANIFEST if test 1285 -ne `wc -c icon/course/course08.27 <<'END_OF_icon/course/course08.27' XString and List Processing. Prof. Ralph Griswold XA course of ten weeks, two times 2 hours a week. Graduate Course. X XData representation, pattern matching, structures. Applications in Xsymbolic mathematics, text analysis, document formatting, cryptography, etc. X XThe course started out with reducing the amount of students to 15. 30 Xdid came. I was so lucky that I could stay as a sort of special Xinvitation of Prof. Griswold. He seems a very, very, intelligent person Xand I am proud to follow the course. It is the last course of this kind Xfor the coming two years. X XHe started out to say that the course is a personal approach of looking Xat CCS by Griswold and others (Dave Hanson cs.) XIt will put the emphasis on concepts, that we will learn ICON is just a Xmatter of coincidence. The homework will never be more then 20 lines of Xcode (gertjan: that does not mean to much in Icon!). The homework will Xbe handed in by electronic mail and a daemon program checks if all the Xhomework is hand in on time. A course news mailing list alias is opened Xso that Ralph can announce things to the students. Ralph's terminal is Xalways on for questions. X XBiography of Ralph: PhD EE Stanford 1961. Promised himself never to do Xany programming. Joined Bell Labs. Started work on Symbolic Mathematics. XTogether with Dave Forber and Ivan Polonsky developed various versions Xof Snobol up to version IV (1965). X1971 joined Univ. of Arizona. Developed Icon in 1976. He has lots of Xhumour like: If you hand your homework in in a weird program layout he Xwill probably throw it all away without looking in to it. After that he Xthinks about it and something you may find that 'new idea' in his next Xcourse! XIcon: Trying to find linguistic facilities to manupilate strings, lists, Xetc. Very little formal mechanism for maupilating text was available Xbefore it was done on computers. A lot was done in numerical mathematics Xetc. Language does not have a concept to think about it. XA lot of ideas in Icon are not implemented in existing languages. PROLOG Xwas thought to be new but actually has a lot of ideas from Snobol and XIcon. X XMSDOS version (public domain) of ICON is due for next week!!!! END_OF_icon/course/course08.27 if test 2168 -ne `wc -c icon/course/course09.12 <<'END_OF_icon/course/course09.12' XHomework: Read Chapter 6-8, take attention to the {null} value X XDon't be tempted to use that info for earlier assignments, in Xanother week we come to the good stuff. X XSETS X==== X s := set( [ 1, "a", [] ] ) X s := set( [ 1, "a", 1, [] ] ) X s := set( [ 1, [], 2, [] ] ) X s := set( [ "ab", "a" || "b" ] ) X Xsome functions for sets are: X member(s, x) -> x X insert(s, x) -> s # push X delete(s, x) -> s # pop X X sort(x) can be used for sets also, it produces a 'list'. X *s and the operators ++ -- etc work as expected X and empy set is set([[]]) in this case *s == 0 X XTABLES X====== X XThey've been used in the language since day one! XInherited from Snobol which was the first language which had it. XIt is tabulating and used for: counting words, cross word references, etc XTables are sets in which every element has some associated value X Xcalling sequence: t := table(x) Xusage example: t[word] +:= 1 X XIf you read in data then you don't know yet what words you are Xgoing to get. So you can put word in without knowing how many and Xwhat kind of. X XThe `sort' procedure is extended in 5.10. Sorting is done by the Xstandard queue sort of Unix. So sorting on assigment value order Xof ambigious bytes is dependent on the Unix version you have. X(4.1bsd acts opposit to 4.2bsd) X Xsort(t,i) could be called with values i=1 or i=2 which stands for Xsorting on index or sorting on value Xso a sort(t,i) could produce X X [ [ , ] [ , ] ... ] [ , , , ... ] X ^ ^ ^ ^ X | | | | X sort(t,1) sort(t,2) sort(t,3) sort(t,4) X X Xi=3 and i=4 give [ , , , , , ... ] Xlike in [ "he", 3, "t", 7, "a", 17 ] (sorted on sort(t, 4) ) XThis 3 and 4 case takes much less space in memory X XRECORDS X======= XThere is for instance a record complex(r,i) Xwhich is actually a record constructor complex( , ) X XEvery time you call complex you creat a record X X z := complex(1.2, 3.5) X z.i +:= 2.7 X XSo z.i is a pointer in this record. X XGeneric operations of all these things X X *s size X ?s random (also polymorphic as * is) X Xend-of-course.9-12 END_OF_icon/course/course09.12 if test 2030 -ne `wc -c icon/course/course09.17 <<'END_OF_icon/course/course09.17' XI could not attend classes because Margot was ill. Boy what a job... END_OF_icon/course/course09.17 if test 69 -ne `wc -c icon/course/course09.23 <<'END_OF_icon/course/course09.23' XC.Sc. 550 - String and List Processing X9/23/85 X XReading Assignment Chapter 11 for the fun stuff in Icon! X XHomework Assignments General Comment: X Only comment if you use bizarre code techniques especially if the code itself is not clear enough. Put your main() on the front. X XThursday 9/25 NO CLASS private meditating session! X daemon will be let loose by 1 pm. X XMT MidTerm is 10/15 (Tuesday) X any objections or comment about that? X XI prefer not to make up examination X 1. I ran out of new assignments and I want to do creative excersises. X 2. ... XBut don't fail to show up. You just get a zero then. X XAssignment 4. deserves some discussion X s := encode(x) y should deliver similar outcome X y := decode(s) as x. For numbers that's okay, for lists etc. X that is quite difficult. XIn this case you cannot represent the physical structure. There is no physical Xstructure between the scalar (null, integer, real, string, cset). XIn lists there is only the [] empty list distinctive. XLists of scalars like encode X X x := ["a",1,2.0,1] X XFor strings and cset it is a slightlyu big deal. XDon't worry about the ascii-control characters in this case. X XCompiling technique: X=================== X X |--------| .u1 |--------| X .icn -> | transl | -> -> | linker | -> object X |--------| .u2 |--------| X ^ X (ucode) | X virtual possible X machine other X code code X XDiscussion on fail and success X============================== X X success -> produces a result X fail -> produces not a result X Xterminology: X X values, variables -> result X result, failure -> outcome X XNow you can describe something without mentioning constantly 'value' or X'variable'. X XThe outcome of if e1 then e2 else e3 Xis e2 if e1 succeeds X e3 if e1 fails X Xother examples in compund expressions X X { e1; e2; e3; ... ; en } outcome en END_OF_icon/course/course09.23 if test 1851 -ne `wc -c icon/course/course10.03 <<'END_OF_icon/course/course10.03' X C.Sc. 550 - String and List Processing X 10/3/85 X Xresult sequences notated as S X---------------- X S(e) = { ... } abstract characterization, not produced X S(if e1 then e2 else e3) = X Xcontext: iteration (every e1 do e2) X X goal-directed evaluation i:=find(s1,s2) like in Algol X X every i := 1 to 10 do f(i) -> every f(1 to 10) X Xoperators and generators o+ stands for + bullet, general operator X------------------------ X X S(e1|e2) = S(e1) o+ S(e2) X XHistorically people were concerned about the "|" operation (Spring, Summer) X Xtake care that x := 1|2|(3 to 7) only results in x:=1 Xsame for write(1 to 7). You need a generator to let this work! X X every write(e1|e2) if e1|e2 then X "e1 then e2" "e1 or e2" X XThe way you use it is a reflection of the contents. X X (1 to 10) \ (1 to 5) -> {1,1,2,1,2,3,1,2,3,4,1,2,3,4,5} X X inf XAn empty result sequence {} just should result in {} but loops. X XWhat is |read() ? X S(|read()) = {s1,s2,s3,....} all the lines of a file X XDefenition is made that it terminates "normally". X XBlack hole evaluation 0 = 1 fails X 0 = |1 evaluation no result X just like while 1 do XNormally Icon programmers don't fall iun to this. X X a := [1,3,7,4,"a"] X S(!a) = {1,3,4,5,4,"a"} X XSo every write(!a) writes a result-sequence XIt does this with X list zero a list every !a:=0 X string (one char substrings) !"abc" -> {"a","b","c"} X record X set X table zero a table every !t:=0 X file &input every write(!&input) produces all the input lines X just as well every line:=&input do X is the same as while line:=read() do X XWhat is S(!10) -> {"1","0"} X XComparing two lists if !a1 == !a2 compares every element of list a1 and a2 X XGenerator procedure are: find, upto, bal XGenerator operators are: !x, i to j, e1 | e2, |e1 X XExtensebilty of the language X---------------------------- X X procedure f(x) X . X . X suspend 1 X . X . X suspend 2 X . X . X end X XExample: X procedure To(i,j) X while i <= j do { X suspend i X i +:= 1 X } X end X XThe environment of the procedure is retained. This is all you need to write Xyour own generators. X X suspend is like every X X procedure f() X suspend(1|3|5) X end X Xis as X S(f()) = {1,3,5} X X end-of-course 10-03-85 END_OF_icon/course/course10.03 if test 2234 -ne `wc -c icon/course/course10.10 <<'END_OF_icon/course/course10.10' X C.Sc. 550 - String and List Processing X 10/10/85 X XToday Ralph started to talk about the home work assignments. He went a little Xin detail about the following exercise: X X procedure ranseq(i) X suspend ?|i X end X XYou can also use result sequences in the wrong way. What would be the outcome Xbe of: X X (1 to 3)(1 to 4, !"abc", 7|6) X X {1,2,3}({1,1,1,1,1,1,2,2,2,2,2,2,3...3,4...4,"a","a","b",...}) X XThis is pretty much a mess. Not what you want at least. XIf you are in doubt then it is good to see what it is doing, try something and Xsee what you get. X XRemark: In Icon there is no way to use variable number of arguments. X The reason is the implementation but the syntax definition, perhaps in a X next release? XVariable number of fields can be used in the standard procedures because they Xare written in another language. X Xbacktracking X============ X X control backtracking X -------------------- X X Icon has automatic 'control backtracking' X (exp1, exp2, exp3, ..., expn) X X when expn fails it goes to exp(n-1) etc. X it is implicit automatic X X data backtracking X ----------------- X X This does not go automatic in Icon, however there are some helps available. X There is an operator <- for that reason, this is best to show with an X example: X X procedure foo() # How to keep the original storage of a[i]? X ... X a[i] := 3 X return a[i] X end X X #--------------- X X procedure foo() # conventional approach X local x X ... X x : = a[i] # save old value X a[i] := 3 X suspend a[i] X a[i] := x # restore X end X X #-------------- X X procedure foo() # use builtin operator X ... X suspend a[i] <- 3 X fail X end X XThere is also a reversible exchange y <-> x X X end-of-notes 10/10/85 END_OF_icon/course/course10.10 if test 1941 -ne `wc -c icon/homework/assign.03 <<'END_OF_icon/homework/assign.03' X C.Sc. 550 - String and List Processing X Homework Assignment 3 X September 16, 1985 X X1. (chaos.icn, 20 points) Do Exercise 7.5 in the Icon book. X Arrange your output in columns, five across. X X2. (qcalls.icn, 25 points) Write a program that computes q(i) X recursively as decribed in Exercise 7.4 in the Icon book and X prints out i, q(i), and the number of calls to compute q(i) X for i = 1, ..., 12. X X3. (comb.icn, 25 points) Do Exercise 7.7 in the Icon book. X Interpret "produce" as "write". Test your program with the X following calls: X X comb("abcd",3) X comb("0123456789",8) X comb("ABCDEFGH",2) X X end-of-assignment-3 END_OF_icon/homework/assign.03 if test 655 -ne `wc -c icon/homework/assign.04 <<'END_OF_icon/homework/assign.04' XHomework Assignment 4 - Due Thursday, October 3, 1985 X X1. (balexp.icn, 15pts). Do Exercise 4.12 in the Icon book. X Consider the operators to be X X + - * / X XRead from standard input and write to standard output. Provide Xyour own data for testing; the daemon with provide its test data Xfor grading. X X X2. (code.icn, 50 pts). Devise a scheme for encoding the various Xtypes of data in Icon as strings. Write a procedure encode(x) Xthat encodes the value of x as a string and a function decode(s) Xthat produces value encoded in s. In general X X x := decode(encode(y)) X Xshould result in x being assigned a value that is the same as the Xvalue of y, except that for structures, the values should be X"similar", not identical. Thus, in X X a := [] X b := decode(encode(a)) X Xthe value assigned to b should be an empty list, but not the Xempty list that is the value of a. X XThis is the first phase of this problem. For this first phase, Xyou should handle the null value, integers, real numbers, Xstrings, csets, and lists. You need not to handle strings and Xcsets that contain characters that would require escape Xconventions for their literal representation. You need not handle Xlists whose values are lists, and so on, but plan ahead. X XDo not provide a main procedure. Instead, include the following Xdeclaration at the beginning of your program: X X link "/usr/ralph/main" X XThis will incorporate a main procedure that tests your encode and Xdecode procedures. (This main procedure will remain the same Xuntil the assignment is due, unless you are informed otherwise, Xbut will be changed when your assignment is run by the daemon.) END_OF_icon/homework/assign.04 if test 1649 -ne `wc -c icon/homework/assign.05 <<'END_OF_icon/homework/assign.05' X Homework Assignment 5 - Due Thursday, October 10, 1985 X X1. (code.icn, 40 points). X Extend your solutionto Problem 2 on Homework Assignment 4 to include Xtables, sets, and record types. You should handle structures that point to Xstructures, but you need not handle loops. You can continue to ignore X"difficult" characters in strings and csets. X XYou should plan to make corrections that may show up as a result of the Xgrading of your original solution. You also may wish to modify your previous Xsolution to take advantage of generators. X X X2. (ranseq.icn, 10pts) X Do Exercise 11.8 in the Icon book. Test your oprocedure with a main Xprocedure that write 50 randomly selected integers between 1 and 100, Xinclusive. X X X3. (ranseql.icn, 10pts) X Do Exercise 11.8 as in the previous problem, but provide a second Xargument, j, that terminates the sequence if it ever produces the value j. For Xexample, ranseql(100,35) should produce a sequence of pseudo-random integers Xbetween 1 and 100, inclusive, but stop with 35 as its last value. Provide a Xmain procedure that tests this example. END_OF_icon/homework/assign.05 if test 1097 -ne `wc -c icon/homework/assign.06 <<'END_OF_icon/homework/assign.06' X C.Sc. 550 - String and List Processing X X Homework Assigment 6 - Due Thursday, October 23, 1985 X X X1. (code.icn, 15 points) Revise your solution of Homework Assignment 5 to use Xstring scanning where appropiate. X X2. (fix.icn, 35 points) Write a procedure infix(exp) that converts an Xexpression exp in binary prefix form to fully parenthesized infix form. For Xexample, the expression X X +(x,-(count,1)) X Xshould be converted to X X (x+(count-1)) X XAssume the operator symbols are +, -, *, and /. X XWrite an inverse procedure prefix(exp) that converts a fully parenthesized Xbinary infix expression to prefiz form. X XUse string scanning in both procedures. Provide a main procedure that reads in Xprefix expressions, one per line, writes out their infix form, converts the Xinfix form back to prefix form, and prints that out also. You may assume the Xinput expressions are syntactically correct. X X end-of-assignment-6 END_OF_icon/homework/assign.06 if test 971 -ne `wc -c icon/homework/assign.08 <<'END_OF_icon/homework/assign.08' X C.Sc. 550 - String and List Processing X X Homework Assigment 8 - Due Thursday, November 7, 1984 X X X1. (comb.icn, 30 points) Redo Problem 3 from Homework Assignment 3, but have Xthe procedure 'generate' the combinations. Provide a main program that writes Xthe same combinations as for the previous assignment. Note: Try to find a Xsolution that uses Icon's expression evaluation mechanism to its best Xadvantage. Grading will be divided evenly between the correctness and the Xquality of your solution. Do not use the previous solution as a guide. X X2. (cosyn.icn, 50 points) The model of string scanning used earlier in Xcoscan.icn is not limited to string analysis. It also can be used for Xsynthesis. Produce a version of the programmer-defined control operation XScan{s,e} as for Problem 2 of Homework Assignment 7, but instead of having it Xreturn the value of e, have it return the value of &subject at the time the Xevaluation of the second argument of Scan is complete. Furthermore, add the Xfollowing synthesis functions: X X append(s) Append the value of s to &subject. X prepend(s) Prepend the value of s to &subject. X Left(i,s) Place &subject at the left of a string of length i X using s as a filler (compare to left(s1,i,s2)) and X note the initial uppercase letter to differentiate X the two. X Right(i,s) As for Left(i,s) above, but at the right. X XFor example, X X Scan{"abc",append("--") & prepend("++")} X Xshould produce X X ++abc-- Xand X Scan{"abc",Left(10,"x")} X Xshould produce X X abcxxxxxxx X XNote: Since &subject may be changed by synthesis functions, its value should Xbe saved and restored following the same protocol that is used for &pos in Xanalysis functions. X XDo not provide your own main procedure, but link in /usr/ralph/synmain in a Xfashion similar to that used in previous assignments. X X end-of-assignment-8 END_OF_icon/homework/assign.08 if test 1897 -ne `wc -c icon/homework/assign.09 <<'END_OF_icon/homework/assign.09' X C.Sc. 550 - String and List Processing X X Homework Assignment 9 - Due Thursday, November 14, 1985 X X X1. (recgen.icn, 50 points) Do Exercise 15.7 in the Icon book. Use the notation Xfor grammars as given in Chapter 15, where uppercase letters denote Xnonterminal symbols and all other characters except the vertical bar stand for Xthemselves as terminal symbols. Assume that the goal will appear as a single Xuppercase letter as the last line of the grammatical specification. X XRead your grammar input from the file /usr/ralph/recgen.gmr. Write the Xrecognizer to /tmp/name/recog.icn, where `name' is your user name. Translate Xand execute recog.icn from your recgen program, giving it X/usr/ralph/recog.test as input. X X2. (lprint.icn, 15 points) Do Exercise 16.2 in the Icon book. Read trees in Xstring form from /usr/ralph/strees.dat, convert them to list form using ltree Xfrom page 172 of the Icon book. (That procedure can be accessed by linking X/usr/icon/ilib/structs). Print the list forms, indenting 3 characters per Xlevel of depth. END_OF_icon/homework/assign.09 if test 1072 -ne `wc -c icon/homework/assign.10 <<'END_OF_icon/homework/assign.10' X C.Sc. 550 - String and List Processing X X Homework Assignment 10 - Due Thursday, December 5, 1985 X X X1. (code.icn, 100 points) Extend the solution of Problem 1 of Homework XAssignment 5 to allow pointer loops and multiple pointers to a single object. X XAny possible object is fair game; do the best you can with types that were not Xconsidered before. You may assume that the program in which the decoding is Xdone contains the same declarations as the program in which the encoding is Xdone. X XExtra credit (10 points): Arrange to handle any character that may occur in a Xstring or cset. X XDo not provide your own main procedure, but link to /usr/ralph/codemain, which Xcontains a main procedure and tests. X X end-of-assignment-10 END_OF_icon/homework/assign.10 if test 785 -ne `wc -c icon/solution/solution.01 <<'END_OF_icon/solution/solution.01' X C.Sc. 550 - String and List Processing X Suggested Solutions to Homework Assignment 1 X September 16, 1985 X X1. nest.icn X X procedure main() X lineno := bcount := 0 X while line := read() do { X lineno +:= 1 X if find("{",line) then bcount +:= 1 X else if find("}",line) then { X bcount -:= 1 X if bcount < 0 then stop("negative count in line ",lineno) X } X } X if bcount > 0 then stop("positive count at end of file") X end X X X2. cases.icn X X procedure main() X ucount := lcount := 0 X while line := read() do { X i := 1 X while j := upto(&lcase,line,i) do { X i := many(&lcase,line,j) X lcount +:= i-j X } X i := 1 X while j := upto(&ucase,line,i) do { X i := many(&ucase,line,j) X ucount +:= i-j X } X } X if lcount = 0 then ratio := "-" X else ration := real(ucount) / lcount X write(right(ucount,10),right(lcount,10)," ",ratio) X end X X X3. palin.icn X X procedure main() X while line := read() do X write(palin(line)) X end X X procedure palin(line) X sent := delete(map(line,&ucase,&lcase),~&lcase) X if sent == reverse(sent) then return line X else fail X end X X procedure delete(s,c) X while i := upto(c,s) do X s[i:many(c,s,i)] := "" X return s X end X X end-of-suggested-solutions-1 END_OF_icon/solution/solution.01 if test 1244 -ne `wc -c icon/solution/solution.03 <<'END_OF_icon/solution/solution.03' X X X Suggested Solutions to Homework Assignment 3 X X1. chaos.icn X X procedure main() X local i X i := 0 X until i = 500 do { X i +:= 1 X write(right(q(i),6)) # write without linefeed X if (i % 5) = 0 then write() # terminate line on 5 columns X } X end X X procedure q(i) X static qmem X local j X initial { X q := table() X qmem[1] := qmem[2] := 1 X } X if j := \qmem[i] then return j X else return qmem[i] := q(i-q(i-1)) + q(i-q(i-2)) X end X X X2. qcalls.icn X X global qcalls X X procedure main() X i := 0 X until i = 12 do { X qcalls := 0 X i +:= 1 X write(right(1,5),right(q(i),6),right(qcalss,7)) X } X end X X X3. comb.icn X X procedure main() X comb("abcd",3) X comb("0123456789",8) X comb("ABCDEFGH",2) X end X X # This procedure makes use of the fact that the general situation X # in forming combinations is that some objects have been selected X # and some remain to be selected. There are no selected objects X # initially, but omn recursive computation, there are. Hence the X # procedure is given a third argument that is omitted in the X # initial call, but is supplied in subsequent recursive calls. X # X X procedure comb(remaining,i,selected) X local c X /selected := "" # supply default X if i = 0 then write(selected) X while c := remaining[i] do { # select one X remaining[1] := "" # and remove it X comb(remaining,i-1,selected || c) X } X end END_OF_icon/solution/solution.03 if test 1577 -ne `wc -c icon/solution/solution.06 <<'END_OF_icon/solution/solution.06' X X C.Sc. 550 - String and List Processing X X Suggested Solutions to Homework Assignment 6 X X X1. code.icn. The only procedure affected by string scanning is pair: X X procedure pair(s) X local i X s ? while i := tab(many('0123456789')) do { X suspend [move(1),move(i)] \ 1 X } X end X X X2. fix.icn. There are many possible approaches to this problem. Here is a X"conservative" one: X X procedure main() X while exp := read() do { X write(exp := infix(exp)) X write(prefix(exp)) X } X end X X procedure infix(exp) X local op, arg1, arg2 X exp ?:= X if { X op := tab(any('+-/*')) & X =="(" & X arg1 := tab(bal(',')) & X move(1) & X arg2 := tab(bal(')')) & X pos(-1) X } then "(" || infix(arg1) || op || infix(arg2) || ")" X return exp X end X X procedure prefix(exp) X local op, arg1, arg2 X exp ?:= X if { X =="(" & X arg1 := tab(bal('+-/*')) & X op := move(1) & X arg2 := tab(bal(')')) & X pos(-1) X } then op || "(" || prefix(arg1) || "," || prefix(arg2) || ")" X return exp X end X XA more "aggressive" approach avoids auxiliary identifiers by using the oprder Xin which string scanning produces strings to the best advantage: X X procedure main() X while exp := read() do { X write(exp := infix(exp)) X write(prefix(exp)) X } X end X X procedure infix(exp) X local rexp X exp ? X if rexp :== tab(any('+-/*')) then X rexp :== =="(" || infix(tab(bal(','))) || (move(1),rexp) || X infix(tab(bal(')'))) || ==")" X else rexp :== tab(0) X return rexp X end X X procedure prefix(exp) X local rexp X exp ? X if rexp :== =="(" || prefix(tab(bal('+-/*'))) then X rexp :== move(1) || rexp || "," || prefix(tab(bal(')'))) || ==")" X else rexp :== tab(0) X return rexp X end X X end-of-solutions-6 END_OF_icon/solution/solution.06 if test 2060 -ne `wc -c icon/solution/solution.08 <<'END_OF_icon/solution/solution.08' X C.Sc. 550 - String and List Processing X X Suggested Solutions to Homework Assignment 8 X X X1. comb.icn X X procedure comb(s, i) X local j X if i < 1 then fail X suspend if i = 1 then !s X else s[j:=1 to *s-i+1] || comb(s[j + 1:0], i-1) X end X X X2. cosyn.icn X X procedure append(s) X suspend &pos <- 1 & .(&subject <- &subject || s) X end X X procedure prepend(s) X suspend &pos <- 1 & .(&subject <- s || &subject) X end X X procedure Right(i, s) X suspend &pos <- 1 & .(&subject <- right(&subject, i, s)) X end X X procedure Left(i, s) X suspend &pos <- 1 & .(&subject <- left(&subject, i, s)) X end X XThe main procedure used for testing follows. The procedure snapshot is from Xthe Icon program library; see TR 85-18 X X link "/usr/icon/ilib/snapshot" X X procedure main() X watch() X every write(Scan{("Hi" | "Ahoy") || " there", X watch(move(2)) || watch(append("!!! ")) || watch(move(4) || X watch(prepend(".")))}) X watch() X wlist := ["Here", "we", "go", "again"] X every write(Scan{!wlist, Left(1 to 3, "+-") & Right(1 to 3, "*.")}) X end X X procedure watch(s) X /s := "" X write("evaluating ...") X snapshot() X suspend s X write("resuming ...") X snapshot() X end X X end-of-suggested-solutions-8 END_OF_icon/solution/solution.08 if test 1364 -ne `wc -c icon/solution/solution.mid <<'END_OF_icon/solution/solution.mid' X C.Sc. 550 - String and List Processing X X Results of Midterm 1 X XGrades X X high 100 X low 75 X X mean 85.12 X median 84 X mode 85 X X XSolutions X X1. X procedure main() X chars := table(0) X every chars[!!&input] +:= 1 X clist := sort(chars,3) X while write(get(clist),":",right(get(clist),10)) X end X X2. X |--------------| X | | X v |--------| | Xa -->--->| 15 | | X ^ |--------| | Xb ----| -----. | | X /|--------| | X / | 10 | | X | |--------| | X | | 20 | | X v |--------| | X | | X \ |--------| | Xc ->---->| .---->-| X |--------| ^ X | .------| X |--------| X X3. X (1) {5,6,7} X (2) {1,2,3,1,2,3,4,2,3,2,3,4} X (3) {1,0,-1,2,1,0,3,2,1} X (4) {1,2,3,1} X (5) {"11","12","13","21","22","23","31","32","33"} X (6) {1,2,3,1,2,3,1,2,3,...} X (7) {1,2,3} X (8) {5,6,7,8,9,10,11,12,13,14,15} X X4. X procedure factorial() X local fact,i X fact := 1 X i := 0 X suspend fact *:= (i +:= |1) X# could have said: suspend fact *:= seq(1) X end X X5a X L(expr2) X S(expr2) +o S(expr3) X X5b X L(expr1) = 0 Xor X L(expr1) = 1 and L(expr3) = 0 Xor X L(expr2) = L(expr3) = 0 X X X end-of-solutions-midterm END_OF_icon/solution/solution.mid if test 1415 -ne `wc -c Received: by megaron.arizona.edu (5.59-1.7/15) id AA24553; Tue, 21 Feb 89 07:18:13 MST Received: by att.ATT.COM (smail2.6 - att-ih) id AA06769; 21 Feb 89 08:14:24 CST (Tue) From: ihuxy!nowlin (Jerry D Nowlin +1 312 979 0441) To: att!arizona!icon-group Subject: Re: tables and &self There are lots of people who look on Icon as a magic lamp and expect it to be able to do anything. That's mostly because Icon is so darn useful right out of the box. We expect it to automatically do all the things we're accustomed to doing explicitly in other languages. I know I sit around sometimes trying to find the simplest Icon solution to things and can't understand why I still have to do initializations and loops and other busy stuff. Consider how many languages give you a data type like tables in the first place. How many of them then let you write a simple procedure that makes initializing identity tables so easy? procedure main() t := selftbl(&ascii) every p := !sort(t) do write("table[",p[1],"] = '",p[2],"'") end procedure selftbl(self) tbl := table() every tbl[s := !self] := s return tbl end I'm just thankful that Icon makes these mundane types of programming tasks so simple and easy. > I found another circumstance where the table(&self) would have been useful, > though it would have been a generalization of what I suggested last time. > In particular, I was needing to sort some records according to the > magnitude of one of their components. In this case, a generalization > of what I had before, If you're in need of a way to sort lists of records I have a record sorting procedure that will let you sort on any field in a record. In fact it will let you recursively sort on a number of different record fields. If you're interested let me know and I can mail it to you or post it to the group. Jerry Nowlin (...!att!ihuxy!nowlin) From @CUNYVM.CUNY.EDU:EM302723@VMTECMEX.BITNET Wed Feb 22 16:01:05 1989 Message-Id: <8902222301.AA26384@megaron.arizona.edu> Received: from cunyvm.cuny.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA26384; Wed, 22 Feb 89 16:01:05 MST Received: from VMTECMEX.BITNET by CUNYVM.CUNY.EDU (IBM VM SMTP R1.1) with BSMTP id 3846; Wed, 22 Feb 89 17:58:33 EST Date: Wed, 22 Feb 89 13:41:09 MEX To: icon-group@arizona.edu From: EM302723%VMTECMEX.BITNET@CUNYVM.CUNY.EDU Comment: CROSSNET mail via SMTP@INTERBIT Date: 22 February 89, 13:39:56 MEX From: Mario Camou Riveroll EM302723 at VMTECMEX To: ICON-GROUP at ARIZONA Hi, all. Is there an implementation of Icon for an IBM 4381 running CP/CMS on VM/SP? Mario Camou R. EM302723@VMTECMEX.BITNET From KARNA@wharton.upenn.edu Fri Mar 10 12:11:20 1989 Received: from REMOTE.DCCS.UPENN.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA00141; Fri, 10 Mar 89 12:11:20 MST Return-Path: Received: from WHARTON.UPENN.EDU by remote.dccs.upenn.edu id AA08241; Fri, 10 Mar 89 14:12:43 EST Message-Id: <8903101912.AA08241@remote.dccs.upenn.edu> Date: Fri, 10 Mar 89 14:11 EST From: KARNA@wharton.upenn.edu Subject: Icon 7.0 and Icon 7.5 To: icon-group@arizona.edu X-Vms-To: IN%"icon-group@arizona.edu" I'm new to the Icon Mailing List, although I've used version 6.1 of Icon off-and-on for about two years. I'm wondering . . . can anyone tell me what the differences are between 6.1 and 7.x (to the most recent version)? -- Karna@wharton.upenn.edu From dscargo@cim-vax.honeywell.com Fri Mar 10 12:21:26 1989 Message-Id: <8903101921.AA00602@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA00602; Fri, 10 Mar 89 12:21:26 MST Date: 10 Mar 89 13:18:00 CST From: "DAVE CARGO" Subject: Icon in Icon To: "icon-group" Out of curiousity, has anyone tried to rewrite the C programs for itran and ilink into Icon to see hom much shorter and easier (and slower) they would be? dsc From kwalker Fri Mar 10 15:16:38 1989 Date: Fri, 10 Mar 89 15:16:38 MST From: "Kenneth Walker" Message-Id: <8903102216.AA08693@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA08693; Fri, 10 Mar 89 15:16:38 MST In-Reply-To: <8903101912.AA08241@remote.dccs.upenn.edu> To: icon-group Subject: Re: Icon 7.0 and Icon 7.5 Date: Fri, 10 Mar 89 14:11 EST From: KARNA@wharton.upenn.edu I'm wondering . . . can anyone tell me what the differences are between 6.1 and 7.x As listed in the University of Arizona technical report TR88-41, Version 7.5 of Icon, the major differences between Version 6 and Verion 7 of Icon are: - New functions, especially for interfacing the operating system and manipulating bits. - Correction of the handling of scanning expressions. - Correction of the handling of co-expression return points and new co-expression facilities. - Declaration of procedures with a variable number of arguments. - The ability to convert potential run-time error to expression failure. - New keywords. - Error traceback, which provides detailed information about the source of run-time errors. Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621 2858 kwalker@Arizona.EDU {uunet|allegra|noao}!arizona!kwalker From payne@unocss.unl.edu Mon Mar 20 20:48:26 1989 Received: from [129.93.1.11] by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA18472; Mon, 20 Mar 89 20:48:26 MST Received: by unocss.unl.edu (4.12/4.7) id AA13992; Mon, 20 Mar 89 21:47:10 cst Date: Mon, 20 Mar 1989 21:46:47 CST From: Matt Payne Reply-To: payne@unocss.unl.edu To: icon-group@arizona.edu Subject: icon for the amiga Message-Id: the file /icon/amiga/amiga7.arc appears to only to have source code in it. How may I obtain icon for my amiga without compiling it myself? Thanks in advance Matt Payne: A proud member of FDR's Small System team 47! -------------------------------------+----------------------------------- Consultant | Internet: conslt10@zeus.unl.edu "Computing and Data Communications" | UUCP: uunet!btni!unocss!payne University of Nebraska at Omaha | Bitnet: CONSLT10@UNOMA1 Omaha, NE 68182 | "No matter where you go..." - B.B. From ralph Tue Mar 21 05:44:34 1989 Date: Tue, 21 Mar 89 05:44:34 MST From: "Ralph Griswold" Message-Id: <8903211244.AA06984@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA06984; Tue, 21 Mar 89 05:44:34 MST To: payne@unocss.unl.edu Subject: Re: icon for the amiga Cc: icon-group In-Reply-To: We do not yet have an executable Version 7 Icon for the Amiga. The source is there provisionally for persons who are trying to compile it. We hope to have executable files before long. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From dscargo@cim-vax.honeywell.com Tue Mar 21 13:19:03 1989 Message-Id: <8903212019.AA00881@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA00881; Tue, 21 Mar 89 13:19:03 MST Date: 21 Mar 89 14:19:00 CST From: "DAVE CARGO" Subject: subscripting expression at a data type To: "icon-group" Once again in my use of Icon to develop some applications I've found what seems like a limitation that, if removed, would simplify my programming. What I've discovered is that setting up ranges in a string (or ranges in a list) is difficult because of a need to establish the limits of the ranges separately. What I was curious about was the establishment of subscripting as a data type. I don't know about the syntax, though I observe that the ":" is used only for subscripting or as part of other tokens. I was imagining something like range := i:j #range is now a subscripting expression new_list := old_list[range] #since range is a subscripting expression # do the subscripting as for old_list[i:j] subscripting expressions could then be stored in other structures, returned as results from functions, etc. This change doesn't look like it would cause too many syntactical problems (from my naive viewpoint), since ":" as an operator doesn't occur outside of subscripting expressions. dsc From keil@apollo.com Tue Mar 21 17:05:48 1989 Received: from APOLLO.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA20583; Tue, 21 Mar 89 17:05:48 MST Received: from apollo.apollo.com by apollo.com id AA15311; Tue, 21 Mar 89 16:57:17 EST Received: by apollo.apollo.com id AA10420; Tue, 21 Mar 89 16:50:26 EST From: Mark Keil Message-Id: <8903212250.AA10420@apollo.apollo.com> Date: Tue, 21 Mar 89 17:29:33 EST Subject: Please add me to your meiling list To: icon-group@arizona.edu Folks: Please add me to your mailing list. My address is keil@apollo.com Thanks, Mark Keil From KARNA@wharton.upenn.edu Tue Mar 21 18:22:28 1989 Received: from REMOTE.DCCS.UPENN.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA23486; Tue, 21 Mar 89 18:22:28 MST Return-Path: Received: from WHARTON.UPENN.EDU by remote.dccs.upenn.edu id AA04272; Tue, 21 Mar 89 20:20:55 EST Message-Id: <8903220120.AA04272@remote.dccs.upenn.edu> Date: Tue, 21 Mar 89 20:22 EST From: KARNA@wharton.upenn.edu Subject: Range data types To: icon-group@arizona.edu X-Vms-To: IN%"icon-group@arizona.edu" Range data types are an interesting, and very useful, addition. The only languages I know of that currently have it are Smalltalk and Actor. It shouldn't be too difficult to add it to Icon. I do agree that the standard Icon "a:b" syntax is the best for this data type. Another use for this kind of data type is as a simplification of an "a to b" generator (so we can have statements like "every i:=range do . . ."). p.s.: When I say that Smalltalk and Actor support this type, they do so in a very limited way. karna@wharton.upenn.edu From ralph Tue Mar 21 18:48:02 1989 Date: Tue, 21 Mar 89 18:48:02 MST From: "Ralph Griswold" Message-Id: <8903220148.AA24083@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA24083; Tue, 21 Mar 89 18:48:02 MST To: KARNA@wharton.upenn.edu Subject: Re: Range data types Cc: icon-group In-Reply-To: <8903220120.AA04272@remote.dccs.upenn.edu> The idea of a range data type for Icon comes up from time to time. In fact, I think I once proposed it in the early days of Icon. There is no conceptual difficulty with implementing it. However, there are many small things that have to be worked out. And *any* new data type adds a lot of things -- not just code and what the data type does, but how it fits in with the rest of the language. In other words, it increases the "semantic volume" of the language. It's easier to see the uses of such an extension than it is to assess the negative impact that is diffuse. Icon already is a huge language and frequently criticized (rightly, in my opinion) for its size. My general view on such possible extensions, which may make some things easier, but not add in a major way to the usefulness of the language, is to be conservative. If such a feature subsumes another or leads to unification of apparently disparate features, I get a lot more excited than as a "stand-alone" enhancement. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From KARNA@wharton.upenn.edu Tue Mar 21 19:49:32 1989 Received: from REMOTE.DCCS.UPENN.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA26097; Tue, 21 Mar 89 19:49:32 MST Return-Path: Received: from WHARTON.UPENN.EDU by remote.dccs.upenn.edu id AA05769; Tue, 21 Mar 89 21:48:09 EST Message-Id: <8903220248.AA05769@remote.dccs.upenn.edu> Date: Tue, 21 Mar 89 21:49 EST From: KARNA@wharton.upenn.edu Subject: Object-Oriented Icon To: icon-group@arizona.edu X-Vms-To: IN%"icon-group@arizona.edu" Does anyone know of any research currently underway regarding object-oriented Icon? I agree with Dr. Griswald -- simply adding the features to Icon is too clumsy (it is yet another case of adding features to an already large language); ideally, the extensions would have to be fully integrated into Icon, directly to the heart of the language. If there is no formal research in the topic, would anyone like to work on it with me (i.e., an "over the network" development scenario)? If there is any research underway, can I join? Talk to you later! -- karna@wharton.upenn.edu From wgg@june.cs.washington.edu Wed Mar 22 16:43:47 1989 Received: from june.cs.washington.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA23574; Wed, 22 Mar 89 16:43:47 MST Received: by june.cs.washington.edu (5.59/6.13+) id AA21302; Wed, 22 Mar 89 14:24:54 PST Date: Wed, 22 Mar 89 14:24:54 PST From: wgg@june.cs.washington.edu (William Griswold) Return-Path: Message-Id: <8903222224.AA21302@june.cs.washington.edu> To: KARNA@wharton.upenn.edu, icon-group@arizona.edu Subject: Re: Object-Oriented Icon >Date: Tue, 21 Mar 89 21:49 EST >From: KARNA@wharton.upenn.edu >Subject: Object-Oriented Icon >To: icon-group@arizona.edu > >Does anyone know of any research currently underway regarding object-oriented >Icon? I agree with Dr. Griswald -- simply adding the features to Icon is >too clumsy (it is yet another case of adding features to an already large >language); ideally, the extensions would have to be fully integrated into >Icon, directly to the heart of the language. > >... > >Talk to you later! > >-- karna@wharton.upenn.edu I have used personalized interpreters to implement what some would call an object-oriented Icon. The additions to the translator were simple, and no changes were required in the interpreter. To really get this right might require creating a new language, rather than extending Icon. For example, a raw record type is a little out of place in an OO language. Also, decisions as to what to do with existing (non-OO) types in Icon would require some tough decisions. A language with two type models is a little awkward, but so are integers implemented in an OO style. Decisions, decisions.... What follows is a ``brief'' write-up on Object-Oriented Icon. Programming in Object Icon Object Icon is an simple extension of Icon that permits the definition of 9 types so that a value carries its valid operations with it. This definition does not support encapsulation. Object Icon will compile old Icon programs. A new user type (class) is defined by the class declaration. class type(field1,field2,...) This defines type as a class possessing each field[i] as an attribute. For example the following definition defines a stack class with attributes st, push, pop, size, and init. class stack(rep,push,pop,size,init) Each attribute is actually an instance variable. Any value may be stored in an instance variable. Instance variables might hold class procedures. The syntax for a class method is procedure type::name(arg1,arg2,...) If name is an attribute of type, creating an instance (object) of type will cause the instance variable name to be initialized to the procedure defined by type::name. When called, a class procedure has an implicit local variable self that contains the value of the instance that is invoking the operation. This permits a class procedure to access the instance variables of the invoking instance. Consider the following class procedure: procedure stack::push(value) push(self.rep,value) return self end This procedure uses self to access the instance variable st to perform a push operation on the list stored in it. A class procedure is accessed through the '$' operator. For example mystack$push("hello") invokes stack::push for mystack, pushing the value "hello" on it. A class procedure can also be accessed directly with the '::' syntax. For example mystack.pop := stack::pop assigns the procedure stack::pop to the pop field of mystack. The operation can also be invoked directly, as in stack::push("world") However, this is unlikely to be meaningful if the push operation accesses the self variable (which in this case would be null). However, this syntax is useful for the object creation operation: mystack := stack::stack() The self variable in stack::stack is null on entry to the procedure, but is initialized during its execution. Here is the implementation of the constructor stack::stack. procedure stack::stack() self := new_stack() self.rep := [] return self end The procedure new_stack is defined implicitly by the system. It calls the alloction function stack, and initializes all the instance variables that have procedures defined for them. This concludes the extensions to basic Icon. The following explains how to take advantage of these definitions to aid programming. Icon's field access operations are polymorphic. This means that the field reference x.field is defined as long as the value x is a record that has a field x. The same is true for class instances. This means that instance variables of the same name in different classes are implicitly and automatically shared (it cannot be prevented). In many cases this overlap is meaningful. For example consider a class array and the above class stack. class array(rep,size,in,out,clear) Both class define a procedure size that returns an integer representing the size of the invoking object: array::size() return *self.rep end stack::size return *self.rep end If some variable in the program knows it has an aggregate of some sort, but doesn't care which kind, it can invoke the size procedure and find its size, regardless of whether its an array or stack. agg_size := some_agg$size() Not only can actual fields be shared, but code implementations can as well. For example if the stack and array were actually implemented as above, the sharing is easy. Suppose array just reused the implementation of stack::size by borrowing it in its constructor function: procedure array::array() self := new_array() self.rep := [] self.size := stack::size return self end This works as expected. Some features that might be expected are not supported. For example, there is no notion of an inheritance declaration such as class stack : aggregate (...) that would declare that a stack has all the instance variables and procedures of aggregate, plus any additionally defined by stack. This might be forthcoming, but to be effective, it must be very general, allowing multiple superclasses and arbitrary hiding of inherited attributes, and redefinition of inherited procedures. As shown above this sharing can be handled explicitly by overlapping instance variable names and assigning a borrowed procedure directly directly into instance variables. See the end of this document for a possible implementation. The following notes on the implementation might be useful. The implementation is accomplished (currently) with a variant translator. The Object Icon source is converted into Icon and then compiled as an Icon program. This translation results in a number of names being changed, possibly obfuscating tracing. As may already be evident, the class notion is based directly on records. The class declaration is translated directly to a record declaration of the same name. This means that type(mystack) == "stack". It also means that calling the constructor procedure stack directly does not initialize stack instances in a meaningful way. The system does not check that a defined procedure actually corresponds to a class definition. For example, the procedure stack::stack defined above does not have a corresponding attribute in the class stack declaration. This means spurious procedures can be defined, but it also allows for definition of the constructor without actually storing it in each instance. Defining the procedure type::name(arg1,arg2,...) results in defining the Icon procedure type_name(self,arg1,arg2,...) Defining a procedure of type_name directly will result in a compile-time error due to the multiple definitions. The call expr$name(arg1,arg2,...) results in defining the call (_self_temp := expr).name(_self_temp,arg1,arg2,...) or some equivalent. Using the variable _self_temp directly is unwise, since its value might get destroyed by a procedure invocation. This is a complete Icon program implementing a stack class. class stack(st,push,pop,size,init) procedure main() mystack := stack::stack() mystack$push("hello") mystack$push("world") size := mystack$size() write("My stack is size ",size) write("popping ",mystack$pop()," ",mystack$pop()) end procedure stack::stack() self := new_stack() self.st := [] return self end procedure stack::push(value) push(self.st,value) return self end procedure stack::pop() return pop(self.st) end procedure stack::size() return *self.st end procedure stack::init() self.st := [] return self end PROPOSED IMPLEMENTATION STUFF To implement class type : supertype1 : supertype2 : ... (field1,field2,...) simply substitute the fields of supertype in front of the fields defined for type. redeclaring a field could either result in an error, or masking the old field (i.e., its initial value). Masking initial values can be done in the new_type operation in the following fashion: procedure new_type() return type(\type_field1 | \supertype_field1 | ... ,...) end resulting in taking the "closest" implementation to the type being defined. The problem with the inheritance approach is that it is difficult to imagine a nice syntax that can hide stuff explicitly in this declaration. Also, this type of sharing does not prohibit the normal sharing of record fields, so that there are two ways to share: not a good idea if clarity is what you're after. It is probably better to leave it the way it is. Also, note that the current method permits sharing class procedure implementations across types independent of field names. This means a procedure can be borrowed without the names being the same. This is important, since type is considered to be independent of implementation. Another problem with the inheritance is that inherited instance variables must get initialized in some way. For instance variables holding class procedures this is not difficult, but it is for others. Normally this should be done by the constructor of the superclass, but the current method does not allow for this in a transparent fashion. This requires some thought: get a prototype, and do a field-for-field copy? From icon-group-request Sat Mar 25 17:34:11 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA04481; Sat, 25 Mar 89 17:34:11 MST Received: by ucbvax.Berkeley.EDU (5.61/1.36) id AA12192; Sat, 25 Mar 89 15:57:53 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 25 Mar 89 22:41:23 GMT From: blake!nealiphc@beaver.cs.washington.edu (Phillip Neal) Organization: Univ of Washington, Seattle Subject: iconic programming languages Message-Id: <1337@blake.acs.washington.edu> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu I am working on an Iconic programming language for image processing on the Macintosh computer. It is a lot like HI-VISUAL. Except it is for a pyramid machine with the Mac as a host. My main question is: How do you manage dyadic operations (for example, add two images) without having the programmer specify the actual memory/image name ? That's all for now. I am Phil Neal at U. of Washington. I can be reached at: nealiphc@blake.washington.edu From ralph Sat Mar 25 17:45:40 1989 Date: Sat, 25 Mar 89 17:45:40 MST From: "Ralph Griswold" Message-Id: <8903260045.AA04887@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA04887; Sat, 25 Mar 89 17:45:40 MST To: blake!nealiphc@beaver.cs.washington.edu Subject: Re: iconic programming languages Cc: icon-group In-Reply-To: <1337@blake.acs.washington.edu> I think the name "Icon" for our programming language has misled you. The Icon programming language has nothing to do with "iconic programming". The name was chosen before the word "icon" came into general use for screen pictograms. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From @UICVM.uic.edu:EM302723@VMTECMEX.BITNET Mon Mar 27 11:03:09 1989 Message-Id: <8903271803.AA11901@megaron.arizona.edu> Received: from uicvm.cc.uic.edu.2.248.128.in-addr.arpa by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA11901; Mon, 27 Mar 89 11:03:09 MST Received: from VMTECMEX.BITNET by UICVM.uic.edu (IBM VM SMTP R1.2) with BSMTP id 5697; Mon, 27 Mar 89 12:02:28 CST Date: Mon, 27 Mar 89 11:58:16 MEX To: icon-group@arizona.edu From: EM302723%VMTECMEX.BITNET@UICVM.uic.edu Comment: CROSSNET mail via SMTP@INTERBIT Date: 27 March 89, 11:55:38 MEX From: Mario Camou Riveroll (5)5-20-89-45 EM302723 at VMTECMEX To: ICON-GROUP at ARIZONA Subject: Re: Object-oriented Icon I also am interested in Object-Oriented Icon. Is it possible to get the preprocessor described by Dr. William Griswold in his posting of 22 March? Mario Camou R. EM302723@VMTECMEX.BITNET From icon-group-request Tue Mar 28 16:35:38 1989 Received: from [10.2.0.78] by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA23942; Tue, 28 Mar 89 16:35:38 MST Received: by ucbvax.Berkeley.EDU (5.61/1.36) id AA26738; Tue, 28 Mar 89 15:11:38 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 28 Mar 89 18:03:27 GMT From: mcvax!hp4nl!botter!star.cs.vu.nl!biep@uunet.uu.net (J A Biep Durieux) Organization: VU Informatica, Amsterdam Subject: Re: iconic programming languages Message-Id: <2221@ski.cs.vu.nl> References: <1337@blake.acs.washington.edu> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu In article <1337@blake.acs.washington.edu>, (Phillip Neal) writes: > I am working on an Iconic programming language Alas! Icon is no iconic language. On the contrary: the name is (by some twisted sense of humor) derived from: "icono*clastic* language". So you iconolatrists should go elsewhere. :-) (BTW, it's a nice trick: Iconoclasts have no reason to destroy the language, as it is supposed to be as iconoclastic as themselves, and iconolatrists cannot destroy it, because it's called "icon", so they would become iconoclasts by doins so.) -- Biep. (biep@cs.vu.nl via mcvax) Who am I to doubt the existence of God? I am only a simple man, I already have trouble enough doubting the existence of my neighbour! From ralph Tue Mar 28 16:45:35 1989 Date: Tue, 28 Mar 89 16:45:35 MST From: "Ralph Griswold" Message-Id: <8903282345.AA24294@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA24294; Tue, 28 Mar 89 16:45:35 MST To: icon-group@arizona.edu, mcvax!hp4nl!botter!star.cs.vu.nl!biep@uunet.uu.net Subject: Re: iconic programming languages In-Reply-To: <2221@ski.cs.vu.nl> I'm sorry to spoil a nice theory, but the name "Icon" for the programming language was not derived from "iconoclastic", although after the fact, the association is a plausible excuse. "Icon" does not stand for anything, nor is it an acronym. From @um.cc.umich.edu:Paul_Abrahams@Wayne-MTS Wed Mar 29 02:12:17 1989 Received: from mailgw.cc.umich.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA16812; Wed, 29 Mar 89 02:12:17 MST Received: from him1.cc.umich.edu by mailgw.cc.umich.edu (5.59/1.0) id AA20839; Wed, 29 Mar 89 04:09:05 EST Received: from Wayne-MTS by um.cc.umich.edu via MTS-Net; Wed, 29 Mar 89 04:11:36 EST Date: Tue, 28 Mar 89 22:55:18 EST From: Paul_Abrahams%Wayne-MTS@um.cc.umich.edu To: icon-group@arizona.edu Message-Id: <130069@Wayne-MTS> Subject: Iconoclasm Is an iconoclastic program one that breaks the Icon interpreter? - Paul Abrahams From shafto@eos.arc.nasa.gov Thu Mar 30 11:18:26 1989 Received: from [128.102.21.2] by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA22299; Thu, 30 Mar 89 11:18:26 MST Received: Thu, 30 Mar 89 10:18:59 PST by eos.arc.nasa.gov (5.59/1.2) Date: Thu, 30 Mar 89 10:18:59 PST From: Michael Shafto Message-Id: <8903301818.AA17088@eos.arc.nasa.gov> To: icon-group@arizona.edu, mcvax!hp4nl!botter!star.cs.vu.nl!biep@uunet.uu.net, ralph@arizona.edu Subject: Re: iconic programming languages Cc: shafto@EOS.ARC.NASA.GOV Ralph -- How can you say that Icon does not stand for anything? It stands for the brightest and best, for truth and creativity, for open systems, for the American way! Mike From icon-group-request Thu Mar 30 14:21:59 1989 Received: from UCBVAX.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA06889; Thu, 30 Mar 89 14:21:59 MST Received: by ucbvax.Berkeley.EDU (5.61/1.36) id AA13620; Thu, 30 Mar 89 12:59:00 -0800 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 30 Mar 89 20:22:42 GMT From: encore!maxzilla!kaufman@husc6.harvard.edu (Lar Kaufman) Organization: Encore Computer Corp, Marlboro, MA Subject: Re: iconic programming languages Message-Id: <5473@xenna.Encore.COM> References: <8903301818.AA17088@eos.arc.nasa.gov> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu In article <8903301818.AA17088@eos.arc.nasa.gov> shafto@EOS.ARC.NASA.GOV (Michael Shafto) writes: >Ralph -- > >How can you say that Icon does not stand for anything? It stands >for the brightest and best, for truth and creativity, for open >systems, for the American way! > >Mike Actually, I have to say that the idea that a name like Icon doesn't stand for anything is a pretty powerful argument that it does stand for "iconoclast." Maybe Ralph should take the attitude of one of our popular authors (whose identity I forget) who was pleased to be told what he meant by what he had written. I don't care - I'll use it anyway. Regarding documentation for the Icon language: Is there any more current/authoritative book in print than "The Implementation of the Icon Programming Language" Griswold & Griswold, Princeton University Press, 1986? -lar "It's about a man, two women, and a revolution. What could be simpler than that?" - Roger Ebert Lar Kaufman <= my opinions kaufman@Encore.com From U379005@HNYKUN11.BITNET Wed Apr 12 12:08:45 1989 Message-Id: <8904121908.AA03717@megaron.arizona.edu> Received: from rvax.ccit.arizona.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA03717; Wed, 12 Apr 89 12:08:45 MST Received: from HNYKUN11.BITNET by rvax.ccit.arizona.edu; Wed, 12 Apr 89 12:04 MST Received: by HNYKUN11 (Mailer X1.25) id 4961; Wed, 12 Apr 89 20:59:09 MET Date: Wed, 12 Apr 89 20:48:59 MET From: bob Subject: ... & now for something completely different ... To: icon-group@arizona.edu Hello, Although I've been keeping up with this newsgroup for some time, I would like to put something quite different to your attention. It's rather a personal request concerning the following: > .................. >> Date: Fri, 24 Mar 89 07:38:06 MST >> From: "Saumya K. Debray" >> Message-Id: <8903241438.AA29859@granjon.arizona.edu> >> Received: by granjon.arizona.edu; Fri, 24 Mar 89 07:38:06 MST >> To: U379005@HNYKUN11.BITNET >> Subject: Re: SB-PROLOG news-group ? >> the current version of sb-prolog (version 2.5) has predicates like >> "clause", "listing", etc., but it does not have a garbage collector >> yet (we're working on a garbage collector right now). there is >> ongoing development of the system (it's our primary research vehicle), >> but as far as I know revisions aren't posted to newsgroups -- the >> new versions are put up for anonymous FTP as and when they become >> available. As I don't have the 'anonymous FTP' facility on BITNET, I wondered if some kind soul on the ICON-group could email me the material concerned. Presently I have the 2.2 version. PATCH/DIFF-'s against mine are allright too. I'll be very much obliged. Thank you. Bob. (u379005@hnykun11) From att!ihlpb!nevin1 Sat Apr 15 04:24:39 1989 Date: Sat, 15 Apr 89 04:24:39 MST Message-Id: <8904151124.AA08811@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA08811; Sat, 15 Apr 89 04:24:39 MST From: ihlpb!nevin1 (Nevin J Liber +1 312 979 4751) To: att!arizona!icon-group Subject: What ever happened to the EZ project? I was looking at an old SIGPLAN Notices (June '83), and I came across the EZ project. The EZ project was an attempt to "unify command and programming languages by using the concepts of high-level string-processing languages, such as SNOBOL4 and Icon". What ever happened to it? It sounded like an intriguing idea, and a nice improvement over the command languages we have now. NEVIN ":-)" LIBER AT&T Bell Laboratories nevin1@ihlpb.ATT.COM (312) 979-4751 From att!ihlpb!nevin1 Sat Apr 15 04:24:42 1989 Date: Sat, 15 Apr 89 04:24:42 MST Message-Id: <8904151124.AA08819@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA08819; Sat, 15 Apr 89 04:24:42 MST From: ihlpb!nevin1 (Nevin J Liber +1 312 979 4751) To: att!arizona!icon-group Subject: Shouldn't main(argl) really be main(argl[])? Shouldn't procedure main(argl) really be declared as procedure main(argl[]) Since there wasn't a way of declaring procedures taking a variable number of parameters until Version 6, I understand how the current declaration came about. But now that we CAN declare a procedure which takes a variable number of parameters, shouldn't this be changed to be more "consistent" with the rest of the language (although this change would break existing code)? For similar reasons (although it's too late for this change), the list(x) function should really try to produce a list resulting from the type conversion of x, instead of producing a list of size x. Prior to Version 6, this didn't matter too much because the only type that could be converted to a list was a list, but with the introduction of sets, and the possible future introduction (someday?? :-)) of ordered sets of unique elements and unordered lists of (potentially) non-unique elements, I feel that it would have been "better" if the list() function were similar to string(), integer(), etc. NEVIN ":-)" LIBER AT&T Bell Laboratories nevin1@ihlpb.ATT.COM (312) 979-4751 From drh@Princeton.EDU Sun Apr 16 06:22:05 1989 Received: from [128.112.0.1] by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA22916; Sun, 16 Apr 89 06:22:05 MST Received: from notecnirp.Princeton.EDU by Princeton.EDU (5.58+++/2.6) id AA13782; Sun, 16 Apr 89 08:41:53 EDT Received: by notecnirp.Princeton.EDU (5.51/1.81) id AA05633; Sun, 16 Apr 89 08:41:43 EDT Date: Sun, 16 Apr 89 08:41:43 EDT From: drh@Princeton.EDU (Dave Hanson) Message-Id: <8904161241.AA05633@notecnirp.Princeton.EDU> To: ihlpb!nevin1@arizona.edu Subject: Re: What ever happened to the EZ project? Cc: icon-group@arizona.edu EZ is alive and well at princeton. there's a paper in POPL '85 that describes developments up to my departure from arizona. and i have students working on processes in EZ and distributed EZ. dave hanson From dscargo@cim-vax.honeywell.com Tue Apr 18 10:52:46 1989 Message-Id: <8904181752.AA08781@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA08781; Tue, 18 Apr 89 10:52:46 MST Date: 18 Apr 89 12:50:00 CST From: "DAVE CARGO" Subject: LaTeX \indexentry to \item conversion To: "texhax" Cc: "icon-group" While reading the LaTeX book and trying to understand about \index, \indexentry, and \item in "theindex" environment I discovered that there was no supplied software for performing the transformation from the .idx file's \indexentry to \item lines. In the spirit of supporting the public domain software's user community, here is a simple Icon program for converting LaTeX .idx files into a format suitable for inclusion into theitem environment. Icon was developed by Ralph Griswold and others. The University of Arizona distributes Icon for a nominal cost. Icon is in the public domain. (Icon is also about the same age at TeX.) Icon processors are available for MS-DOS, VAX/VMS, and many UNIX systems. Many systems that use TeX probably also have Icon. Icon is close to ideal for writing character and string manipulation functions, since many features that have to be written by hand or provided by run time libraries are available as language primitives. ## latexidx -- latex index file manipulate # Author: David S. Cargo, Minneapolis, MN 55408 # Rights: Released into the public domain. # Warrantee: No warrantee is expressed or implied. # # Input: a latex .idx file containing the \indexentry lines # Output: \item lines sorted in order by entry value, # with page references put into sorted order. # # Processing: # While lines are available from standard input # Read a line containing an \indexentry # If there is no table entry for it # Then create an empty page number set for it # Add the page number to the page number set # Sort the table of index entry topics # For all entries # Sort the set of page references # Write an \item entry for each entry and the page references # # Limitations: # Items must not contain opening nor closing braces # Length of index handled depends on implementation limits of memory alloc. # Page numbers must be integers (no roman numerals) # Sort key formed by mapping to lower case and removing leading articles # (a separate function is used to produce the sort key, simplifying # customization)--otherwise sorting is done in ASCII order # record item(entry, page_set) procedure main() # no parameters, reading from stdin entries := table() # create the table for entries while s := read() do # read strings from standard input { s := s[upto('{',s)+1:0] # delete up to the opening brace entryval := s[1:upto('}', s)] # the item goes up to the closing brace key := reform(entryval) # allow the sort key to be different if /entries[key] # if the entry is null # store the original entryval and then entries[key] := item(entryval,set([])) # add the supplied page num to the set # use a 0 if the page num is not int. entries[key].page_set ++:= set([integer(s[upto('{',s)+1:-1]) | 0]) } entries := sort(entries, 3) # sort items by entry value # dequeue the key while one_entry := get(entries) do { # discard the sort key and # dequeue and sort the set into a list one_entry := get(entries) # silently discard page 0 if referenced page_list := sort(one_entry.page_set -- set([0])) refs := string(get(page_list)) # dequeue first int and convert to str # dequeue rest of page nums and append while (refs ||:= ", " || string(get(page_list))) write("\\item ", one_entry.entry, " ", refs) } return end # reform - modify the item to enforce sort order appropriately procedure reform(item) # map to lowercase item := map(item) # drop leading article if present if match("a ", item) then return item[3:0] if match("an ", item) then return item[4:0] if match("the ", item) then return item[5:0] return item end From kwalker Wed Apr 19 09:48:10 1989 Date: Wed, 19 Apr 89 09:48:10 MST From: "Kenneth Walker" Message-Id: <8904191648.AA09971@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA09971; Wed, 19 Apr 89 09:48:10 MST In-Reply-To: <8904151124.AA08819@megaron.arizona.edu> To: icon-group Subject: Re: Shouldn't main(argl) really be main(argl[])? > Date: Sat, 15 Apr 89 04:24:42 MST > From: ihlpb!nevin1 (Nevin J Liber +1 312 979 4751) > > Shouldn't > > procedure main(argl) > > really be declared as > > procedure main(argl[]) > > Since there wasn't a way of declaring procedures taking a variable > number of parameters until Version 6, I understand how the current > declaration came about. But now that we CAN declare a procedure which > takes a variable number of parameters, shouldn't this be changed to > be more "consistent" with the rest of the language (although this > change would break existing code)? Yes, logically it should be done that way, but do you have any idea how many programs would be broken?. The transition would be quite painful for a lot of people. While I would like to see the change, I don't think the improvement justifies the problems it would cause. > For similar reasons (although it's too late for this change), the > list(x) function should really try to produce a list resulting from the > type conversion of x, instead of producing a list of size x. Prior to Version > 6, this didn't matter too much because the only type that could be converted > to a list was a list, but with the introduction of sets, and the possible > future introduction (someday?? :-)) of ordered sets of unique elements > and unordered lists of (potentially) non-unique elements, I feel that it > would have been "better" if the list() function were similar to string(), > integer(), etc. I agree that it would be nice if there was a consistent set of functions for type conversions and another set for creating structures. (Maybe the next language someone designs will be so perfect that no one will find any of these mildly annoying inconsistencies :-) Ken Walker / Computer Science Dept / Univ of Arizona / Tucson, AZ 85721 +1 602 621 2858 kwalker@Arizona.EDU {uunet|allegra|noao}!arizona!kwalker From HJJaeger.ANTropos@DMZRZU71.BITNET Wed Apr 19 10:30:11 1989 Received: from rvax.ccit.arizona.edu by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA12593; Wed, 19 Apr 89 10:30:11 MST Received: from DMZRZU5P.BITNET by rvax.ccit.arizona.edu; Wed, 19 Apr 89 10:26 MST Received: from DMZRZU71-UNI-MAINZ--GERMANY by DMZRZU5P.BITNET; Wed, 19 Apr 89 16:07 N Date: Wed, 19 Apr 89 16:06+0200 From: HJJaeger@DMZRZU71.BITNET Subject: index To: icon-group@arizona.edu Message-Id: <890419140637.306720@DMZRZU71-UNI-MAINZ--GERMANY> send index From icon-group-request Wed Apr 19 20:27:47 1989 Received: from ucbvax.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA16525; Wed, 19 Apr 89 20:27:47 MST Received: by ucbvax.Berkeley.EDU (5.61/1.36) id AA27899; Wed, 19 Apr 89 20:25:22 -0700 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 19 Apr 89 20:11:49 GMT From: osu-cis!mstar!resource!root@tut.cis.ohio-state.edu (Super user) Organization: Resource Systems Subject: Easel Message-Id: <979@resource.UUCP> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu Has anyone heard of a developement language called "EASEL" (company unknown). It's supposed to be big into windowing, and icons. I belive a company called COMSHARE used it to develop a product called Commander-EIS. Any information would greatly be appreciated. Thanks, Bryan tut!osu-cis!resource!bryan bryan@resource.uucp From lti!talmage@bu-it.BU.EDU Tue Apr 25 14:11:28 1989 Received: from BU-IT.BU.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA15428; Tue, 25 Apr 89 14:11:28 MST Received: from BUITA.BU.EDU by bu-it.BU.EDU (5.58/4.7) id AA04982; Tue, 25 Apr 89 17:04:23 EDT Received: by buita.bu.edu (3.2/4.7) id AA28889; Tue, 25 Apr 89 17:07:17 EDT Received: from waltham.lti.com by lti.com (4.0/SMI-4.0) id AA03123; Tue, 25 Apr 89 11:25:58 EDT Date: Tue, 25 Apr 89 11:25:58 EDT From: lti!talmage@bu-it.BU.EDU (David Talmage) Message-Id: <8904251525.AA03123@lti.com> Received: by waltham.lti.com (4.0/SMI-4.0) id AA00608; Tue, 25 Apr 89 11:25:42 EDT To: icon-group@arizona.edu Subject: Porting Icon: How long? What problems? Here are some questions for those who have ported Icon to a new system. I want to run Icon Version 7.5 (or greater?) on my Amiga. I've been using Version 6 for over a year and have been anxiously awaiting the announcement of the new version for My Favorite Micro. It looks as though I'll have some time and disk space this summer, so maybe I'll do it myself. What part of porting the hierarchical file system version of "Icon for porting" was easy for you? What problems did you encounter? Are the system-dependent things documented and isolated to a few files? How long did you expect to take to do the port? How long did it really take? I'm usually pretty good at figuring out other people's code. Did you have any trouble understanding what you had to do and how the Icon implementers did it? Does "Icon for porting" come with instructions for adding new functions to the language? For example, Version 6 on the Amiga lets me use the built-in speech synthesizer. I've used it to make my Amiga pronounce Esperanto words. I'll think about adding an AREXX [1] port too. I don't expect this to be a trivial project, really, but I do expect it to be fun. The possibility of Fame And Fortune is also intriguing ;-) Oh yes, and the groupies. Especially the groupies ;-) ;-) Please send me e-mail about this if you want to. I'll try to summarize the replies I receive in about two weeks. David Talmage ------------------------------ Notes: [1] AREXX is the Amiga version of IBM's REXX langauge. It was implemented on the Amiga by William Hawes. It includes a way for programs to communicate with each other (through "AREXX ports") and has found its way into many commercial and public domain programs. ------------------------------------------------------------------------------ David W. Talmage, Systems Programmer ...!{buita,bbn}!lti!talmage Language Technology, Inc. talmage%lti.uucp@bu-it.bu.edu 27 Congress St., Salem, MA 01970 (508) 741-1507 From cjeffery Tue Apr 25 14:55:40 1989 Date: Tue, 25 Apr 89 14:55:40 MST From: "Clinton Jeffery" Message-Id: <8904252155.AA17482@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA17482; Tue, 25 Apr 89 14:55:40 MST To: icon-group Subject: Porting Icon (Amiga); how long, what problems? This is in response to a query by David Talmadge. I have finished a port of Icon version 7.5 to the Amiga using Aztec C 3.6. A version using Lattice 5.0.2 has been delayed by compiler bugs. The port will be validated on the Icon test suite and should be available by early summer (I might be persuaded to send out an unofficial copy if promised something interesting like an AREXX interface). The changes were mostly minor and easy, but still required some attention to detail. I would be happy to discuss them, but perhaps you would prefer to wait and read them for yourself! Actually, REXX and Icon provide mostly overlapping functionality. REXX has the advantage of ports, and Icon has the advantage of public domain status, a clean implementation with publicly available source code, and a superior expression evaluation paradigm (I have a friend who is a REXX guru in the IBM world, so my evaluation is not totally one-sided). I would rather add the concept of ports to Icon than add an interface to a product (AREXX) that I would have to go out and buy in order to use. From att!ihlpb!nevin1 Tue Apr 25 17:41:39 1989 Date: Tue, 25 Apr 89 17:41:39 MST Message-Id: <8904260041.AA26449@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA26449; Tue, 25 Apr 89 17:41:39 MST From: ihlpb!nevin1 (Nevin J Liber +1 312 979 4751) To: att!arizona!icon-group Cc: att!arizona!kwalker Subject: Re: Shouldn't main(argl) really be main(argl[])? NL=Nevin Liber, KW=Ken Walker NL> Shouldn't NL> NL> procedure main(argl) NL> NL> really be declared as NL> NL> procedure main(argl[]) KW> Yes, logically it should be done that way, but do you have any idea KW> how many programs would be broken?. The transition would be quite KW> painful for a lot of people. Would it really be all that painful? It would be fairly easy to write an Icon program to do the conversion. Unless I have overlooked a case, all that would be needed to be done is: a) Change the occurance, if any (at most one per program), of procedure main(ArgumentList) to procedure main(ArgumentList[]) to take care of the declaration (needed at compile time), and b) If (a) was done, then add the following to the beginning of the initial clause, if any, of main, as well as to the beginning of the body of main: if 1 = *ArgumentList & "list" == type(ArgumentList[1]) then ArgumentList := ArgumentList[1] to take care of those people who might call main() from within their program (the run time case), although personally I don't think that there are many programs which call main() recursively within a program. KW> While I would like to see the change, I KW> don't think the improvement justifies the problems it would cause. The fixing of, say, the string scanning environment probably caused more problems than this change would (and yes, I do think the string scanning fix was justified). NEVIN ":-)" LIBER AT&T Bell Laboratories nevin1@ihlpb.ATT.COM (312) 979-4751 From ralph Tue Apr 25 18:19:31 1989 Date: Tue, 25 Apr 89 18:19:31 MST From: "Ralph Griswold" Message-Id: <8904260119.AA28109@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA28109; Tue, 25 Apr 89 18:19:31 MST To: ihlpb!nevin1 Subject: Re: Shouldn't main(argl) really be main(argl[])? Cc: icon-group In-Reply-To: <8904260041.AA26449@megaron.arizona.edu> Yes, the change, which would be nice in hindsight, is not practical to make now. It isn't just a matter of changing source programs. There are a lot of object programs around. This is an object lesson is getting stuck with the decisions you make early on. Incidentally, the change in scanning environments seems to be largely transparent to most programs. Probably because it essentially fixed a bug. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From att!ihlpb!nevin1 Tue Apr 25 21:09:06 1989 Date: Tue, 25 Apr 89 21:09:06 MST Message-Id: <8904260409.AA07201@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA07201; Tue, 25 Apr 89 21:09:06 MST From: ihlpb!nevin1 (Nevin J Liber +1 312 979 4751) To: att!arizona!icon-group Subject: Re: Shouldn't main(argl) really be main(argl[])? >It isn't just a matter of changing source programs. There >are a lot of object programs around. Just wondering: what do people who only have objects around do whenever a new version of Icon gets released? NEVIN ":-)" LIBER AT&T Bell Laboratories nevin1@ihlpb.ATT.COM (312) 979-4751 From ralph Wed Apr 26 05:26:19 1989 Date: Wed, 26 Apr 89 05:26:19 MST From: "Ralph Griswold" Message-Id: <8904261226.AA25706@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA25706; Wed, 26 Apr 89 05:26:19 MST To: ihlpb!nevin1 Subject: Re: Shouldn't main(argl) really be main(argl[])? Cc: icon-group In-Reply-To: <8904260409.AA07201@megaron.arizona.edu> Because of the way that Icon references the run-time system by an absolute path, one way to install a new version is to use a different path than that for old versions, leaving old object files referencing old versions. Not pleasant, but it's done. I did not state my point well. It's not old object files that cause problems. It's recompiling the source, possibly by folks who know nothing about Icon. For example, Icon is used here for a number of utilities. When a new verion of Icon is installed, our staff may run scripts to bring object files up to date. Obviously having to change the source for a new version is undesirable in such cases. Icon source also is referenced in many scripts here where existing code is concatenated with newly generated code. Source incompatib- ilities between versions tend to cause things to "break" unexpectedly, some- times long after the change for infrequently run scripts. As another example, we have performance measuring software that extracts Icon programs from archive files and runs them. I'd not relish de-archiving the thousands of programs from a couple of hundred archives, processing them to take care of arguments to main(), and re-archiving them. If I were on the receiving end of this cosmetic improvement of Icon, I probably would not be very happy about the grief it caused me. Thse are just examples. The underlying problem is that when a programming language is used extensively, making changes that are not upward compatible becomes impractical. There are a lot of things we'd like to change, but we can't justify the changes because of the annoyance they would cause users. So we live with it. One of the more amusing (?) examples I know of in the general area of "being stuck with decisions made in the past" is the EBCDIC collating sequence. There are gaps in the middle of the sequences for upper- and lowercase letters, where non-alphabetic characters appear. Obviously undesirable if you're sorting anything containing both letters and these non-alphabetic characters. This curiosity is a carry over from the 6-bit BCD collating sequence used by IBM. I investigated the source of this problem once and was told it had to do with the way BCD characters were encoded on magnetic tape in some early parity scheme. Imagine how far this early decision has spread and how much grief it has caused over the years. Yet IBM was unwilling to make the change (in the 1960s) when going from BCD to EBCDIC. Now it's permanently institutionalized. From LEICHTER@Venus.YCC.Yale.Edu Wed Apr 26 07:31:52 1989 Message-Id: <8904261431.AA29537@megaron.arizona.edu> Received: from VENUS.YCC.YALE.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA29537; Wed, 26 Apr 89 07:31:52 MST Date: Wed, 26 Apr 89 10:34 EDT From: "Jerry Leichter (LEICHTER-JERRY@CS.YALE.EDU)" Subject: Re: Shouldn't main(argl) really be main(argl[])? To: icon-group@arizona.edu X-Vms-To: IN%"icon-group@arizona.EDU" There's one alternative: Define a new "main entry point", say "main_program". It would be defined as "main_program(argl[])". The rules for defining how a program is to start up are: - If only main is present, call it as previously; - If only main_program is present, call it; - If both are present, call main as always (but perhaps issue a warning). -- Jerry From ralph Thu Apr 27 05:17:18 1989 Date: Thu, 27 Apr 89 05:17:18 MST From: "Ralph Griswold" Message-Id: <8904271217.AA01264@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA01264; Thu, 27 Apr 89 05:17:18 MST To: icon-group Subject: Icon under Ultrix There are a couple of problems with Version 7.x of Icon running under recent releases of Ultrix. If you're having problems, here is a fix and a workaround. 1. One problem is that fopen(s,"wb") fails under recent Ultrix. Locate occurrences of "wb" in the icont directory and change them to "w". 2. Opening a file allocates space before Icon is prepared under the "expandable regions" memory configuration. The workaround is to add #define FixedRegions to h/define.h. This disables region expansion, but region sizes can be set large if needed by using environment variables. We'll take care of these problems (including supporting expandable memory regions) in Version 7.6 of Icon. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From ralph Thu Apr 27 07:28:48 1989 Date: Thu, 27 Apr 89 07:28:48 MST From: "Ralph Griswold" Message-Id: <8904271428.AA05925@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA05925; Thu, 27 Apr 89 07:28:48 MST To: icon-group Subject: Version 7.x of Icon under Ultrix Bill Idsardi reminded me that there's also a "rb" in a fopen that needs changing to "r". Summary: icont/link.c: "wb" -> "w" iconx/imain.c: "rb" -> "r" (2 places) Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From keil@apollo.com Thu Apr 27 08:57:11 1989 Received: from APOLLO.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA09616; Thu, 27 Apr 89 08:57:11 MST Received: from xuucp.ch.apollo.com by amway.apollo.com id Thu, 27 Apr 89 11:51:58 EDT Received: by xuucp.ch.apollo.com id ; Tue, 25 Apr 89 23:20:19 EDT From: Mark Keil Message-Id: <8904260320.AA12450@xuucp.ch.apollo.com> Date: Tue, 25 Apr 89 22:52:55 EDT Subject: Re: Shouldn't main(argl) really be main(argl[])? To: ralph@arizona.edu Cc: icon-group@arizona.edu Ralph: You said: << It isn't just a matter of changing source programs. There are a lot of object programs around. >> But,... won't all the object files have to be rebuilt when the version code changes the next time? That would seem to be the time to make such a change. Also, I suppose Itran could also be made to accept both forms of argl or argl[] , with a warning about old style useage for the former case. That way folks would not immediately have to change their source. Is the current way (argl) special cased? Would the logical way (argl[]) be more general, and thus an easy change? (I havn't actually looked...) Then again, if it takes a lot of work it might not be worth it. Mark Mark Keil Apollo Computer, Chelmsford MA 01824 +1 508-256-6600 x2495 keil@apollo.com / {decvax,mit-erl,yale}!apollo!keil From att!ihlpb!nevin1 Thu Apr 27 15:46:58 1989 Date: Thu, 27 Apr 89 15:46:58 MST Message-Id: <8904272246.AA12007@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA12007; Thu, 27 Apr 89 15:46:58 MST From: ihlpb!nevin1 (Nevin J Liber +1 312 979 4751) To: Mark Keil Cc: att!arizona!icon-group Subject: Re: Shouldn't main(argl) really be main(argl[])? Mark Keil (keil@apollo.com) writes: > I suppose Itran could also be made to accept both forms of argl or argl[] , > with a warning about old style useage for the former case. This doesn't really help. If the change from "main(argl)" to "main(argl[])" were made, then the new meaning for main(argl) is to store the first parameter, if it exists, in the variable argl (as a string [assuming this is the initial call to main()], not a list of strings), and ignore any other parameters. It would have to accept either one or the other (perhaps via a command line option, but I don't really like that solution. You should not have to remember whether or not your code is pre-argl[] or post-argl[]; that should be done automatically) but not both; otherwise, all we are doing is moving from one exception case to another. NEVIN ":-)" LIBER AT&T Bell Laboratories nevin1@ihlpb.ATT.COM (312) 979-4751 From att!ihlpb!att!arizona!cheyenne Thu Apr 27 17:55:08 1989 Received: by megaron.arizona.edu (5.59-1.7/15) id AA18147; Thu, 27 Apr 89 17:55:08 MST Date: Thu, 27 Apr 89 17:49:44 MST From: "Cheyenne Wills" Message-Id: <8904280049.AA17593@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA17593; Thu, 27 Apr 89 17:49:44 MST In-Reply-To: <8904272246.AA12007@megaron.arizona.edu> To: ihlpb!arpa!apollo.com!keil, ihlpb!nevin1 Subject: Re: Shouldn't main(argl) really be main(argl[])? Cc: ihlpb!att!arizona!icon-group There is another thing to look at here.. The purpose of the format of proc(arglist[]) is to place the "remaining" parms into a list. The system invocation of main has already placed the arguments into a list so what one would get is a list with a single item, which is a list of the arguments. Think of it this way: main is called with the following "format": main([ arg1, arg2, arg3 ]) to have main use the format of "procedure main(argl[])" would cause the call to main look like: main([ [arg1, arg2, arg3 ] ]) Cheyenne From icon-group-request Mon May 1 22:15:18 1989 Received: from ucbvax.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA15323; Mon, 1 May 89 22:15:18 MST Received: by ucbvax.Berkeley.EDU (5.61/1.36) id AA08093; Mon, 1 May 89 21:59:11 -0700 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 1 May 89 23:08:39 GMT From: umigw!umiami!slores@handies.ucar.edu (Stanislaw L. Olejniczak) Organization: University of Miami (IR) Subject: SoftEng or CS Graduate Program Search Message-Id: <600@umiami.miami.edu> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu I would very much appreciate, on my and many other prospective graduate students' behalf, your comments on graduate software engineering programs. I have been reading brochures from various schools, collected various rankings and read a couple books about graduate programs in software engineering or computer science. What I am asking for in this message are personal opinions, observations and comments. Which school and department do you think is a good place to study Software Engineering or Computer Science with Software Engineering emphasis? Why do you think a particular department is a good place to spend a couple years getting a Master's, and later, a Ph.D.? What are its strength? What are its weaknesses? Where do the graduates go? What kind of research is being conducted? Who (if not yourself) is a good person to contact there? What are other comments you would like to make that I have not asked about? All comments you will send will be appreciated. Let me apologize for posting this message again, and for posting it this time to numerous newsgroups. When I have initially posted this request, I have offered to send summaries to any interested person. I have received several dozens of requests for the summaries. I have received a small handful of replies on the subject. After waiting now a considerable, for Newsnet, time, I have decided I did not post it to the right groups; or all the right people did not get to see this. Thus, this second, and final, attempt. To those who had previously replied, my many thanks. For those who had requested or will request summaries, I will post them to you after I feel reasonably certain I have received all replies to this second posting. To those who will reply, many, many thanks, from me and from the numerous prospective graduate students who will embark on more successful graduate studies thanks to the time you take off your busy schedules to advise. P.S. If you are so kind as to send your comments but would NOT want be identified in the summary, please let me know. -- ---- Stan Olejniczak Internet: slores@umiami.miami.edu University of Miami UUCP: {uunet!gould}!umbio!solejni Miami, Florida, USA BITNET: SLORES@UMIAMI Voice: (305)-547-6571 FAX:305-547-6412 My opinions cannot possibly represent the views of anyone else! From sboisen@BBN.COM Tue May 2 08:34:08 1989 Message-Id: <8905021534.AA14060@megaron.arizona.edu> Received: from REGULUS.BBN.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA14060; Tue, 2 May 89 08:34:08 MST To: icon-group@arizona.edu Subject: looking for a simple recognizer From: Sean Boisen Sender: sboisen@BBN.COM Reply-To: sboisen@BBN.COM Date: Tue, 2 May 89 11:35:52 EDT I need to do some quick-and-dirty parsing of English sentences, and while my first instinct is to reach for Prolog and DCG's, i thought i'd query this list to see if somebody already has a good Icon solution to share. What i want is a standard top-down, recursive-descent, backtracking recognizer: i'd really like to have a declarative format for lexicon and grammar rules, however, because i expect to change them a lot. Are people doing this in Icon? I'm sure i could start with what's in the Icon book, and add the details to deal with white-space delimited tokens, etc., but why re-invent the wheel if it's already out there, right? Here's your big chance to show what a great language Icon is (actually i'm already convinced, but this kind of application differs from my typical use, things like small text filters and their kin). ........................................ Sean Boisen -- sboisen@bbn.com BBN Systems and Technologies Corporation, Cambridge MA Disclaimer: these opinions void where prohibited by lawyers. From icon-group-request Fri May 5 02:59:54 1989 Received: from ucbvax.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA21438; Fri, 5 May 89 02:59:54 MST Received: by ucbvax.Berkeley.EDU (5.61/1.36) id AA15583; Fri, 5 May 89 02:56:25 -0700 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 5 May 89 01:31:08 GMT From: hubcap!ncrcae!gollum!rolandi@gatech.edu (wgr) Organization: e&m columbia Subject: installing Icon on an NCR TOWER 600 Message-Id: <233@gollum.UUCP> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu Has anyone had any experience installing Icon on an NCR TOWER 600? I have the source code but there is no documented installation procedure specifically for NCR Unix machines. Any clues before we reinvent the wheel? Walter Rolandi rolandi@ncrcae.Columbia.NCR.COM (insert your feed here)!ncrlnk!ncrcae!rolandi (803) 791 6693 From icon-group-request Sun May 7 18:30:21 1989 Received: from ucbvax.Berkeley.EDU by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA22636; Sun, 7 May 89 18:30:21 MST Received: by ucbvax.Berkeley.EDU (5.61/1.36) id AA25526; Sun, 7 May 89 18:27:22 -0700 Received: from USENET by ucbvax.Berkeley.EDU with netnews for icon-group@arizona.edu (icon-group@arizona.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 8 May 89 01:10:17 GMT From: mailrus!jarvis.csri.toronto.edu!turing.toronto.edu!tarvydas@rutgers.edu (Paul Tarvydas) Organization: University of Toronto, CSRI Subject: need hints re. matching across lines Message-Id: <89May7.211023edt.4600@turing.toronto.edu> Sender: icon-group-request@arizona.edu To: icon-group@arizona.edu I'd like to solicit suggestions on how to solve the following problem (neatly and efficiently). I need to experiment with a some ideas for a post-pass optimizer (peephole optimizer) for the output from a particular compiler. The problem consists of scanning a file of assembler code and replacing certain blocks of 10 or so lines with smaller blocks of code. A few substrings from the original blocks (eg. certain operands) need to be pasted into the replacement blocks. For example, something like movl x,r0 addl2 #2,r0 movl r0,r1 could be replaced by addl3 #2,r0,r1. The goal is to measure how effective a certain set of such optimizations will be, before actually building a production-version optimizer. I'm quite sure that Icon is the appropriate tool for such experimentation, but the solutions that I'm coming up with seem to be too cumbersome, due to my inexperience with iconomic philosophy. I feel that I should be able to treat the input file as a "string" and use backtracking pattern matches to find the interesting pieces of code while simply emitting rejected chunks of code, but, I can't see how to write this cleanly in Icon (brain-damage I've suffered from the teenage APL abuse makes me want to believe that this is really a "one-liner"...). Hints would be appreciated. thanx Paul Tarvydas tarvydas@tsctrl (or tarvydas@turing.toronto.edu) From att!ihuxy!nowlin Mon May 8 07:16:53 1989 Date: Mon, 8 May 89 07:16:53 MST Message-Id: <8905081416.AA17400@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA17400; Mon, 8 May 89 07:16:53 MST From: ihuxy!nowlin (Jerry D Nowlin +1 312 979 0441) To: att!arizona!icon-group Subject: Re: need hints (peephole optimization) > I'd like to solicit suggestions on how to solve the following > problem (neatly and efficiently). > > I need to experiment with a some ideas for a post-pass optimizer > (peephole optimizer) for the output from a particular compiler. > The problem consists of scanning a file of assembler code > and replacing certain blocks of 10 or so lines with smaller > blocks of code. A few substrings from the original blocks > (eg. certain operands) need to be pasted into the replacement > blocks. For example, something like > > movl x,r0 > addl2 #2,r0 > movl r0,r1 > > could be replaced by > > addl3 #2,r0,r1. > > The goal is to measure how effective a certain set of such optimizations > will be, before actually building a production-version optimizer. > I'm quite sure that Icon is the appropriate tool for such experimentation, > but the solutions that I'm coming up with seem to be too cumbersome, due > to my inexperience with iconomic philosophy. > > I feel that I should be able to treat the input file as a "string" > and use backtracking pattern matches to find the interesting > pieces of code while simply emitting rejected chunks of code, but, > I can't see how to write this cleanly in Icon > (brain-damage I've suffered from the teenage APL abuse makes me > want to believe that this is really a "one-liner"...). > > Hints would be appreciated. > > thanx > Paul Tarvydas > tarvydas@tsctrl (or tarvydas@turing.toronto.edu) The main obstacle I see to your plan is using the entire input file as a string. If you could logically break the file up into smaller sections, with boundaries that you know local optimizations won't cross, you could process smaller strings and make your scanning algorithm less complicated. The concept of a basic block of assembler that can't be jumped into or out of, except at the boundaries, would seem to be a logical subset of the input file to try local optimizations on. For example, any block of code that is bounded at the top by a label or a preceding jump instruction and bounded at the bottom by a jump instruction or a subsequent label would constitute a basic block of code. (An over simplification but you get the idea.) In my experience, the assembler that's generated by compilers contains relatively small basic blocks. You could completely parse a basic block into a list of instructions and arguments and do your local optimizations without worrying about scanning at the same time. This may not be the kind of hint you were looking for but the thought of scanning an entire file of assembly language as a single string sounds like a bad idea to me. Jerry Nowlin (...!att!ihuxy!nowlin) From dscargo@cim-vax.honeywell.com Tue May 16 12:11:32 1989 Message-Id: <8905161911.AA04838@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA04838; Tue, 16 May 89 12:11:32 MST Date: 16 May 89 13:53:00 CST From: "DAVE CARGO" Subject: workalikes for lex and yacc To: "icon-group" Has anybody developed tools for Icon similar to Unix lex and yacc? Something for describing tokens and generating a tokenizer, and something for defining syntax and generating a parser? I've been working on a project where C is used for character handling, but I think Icon would be better. The problem with using Icon compared with C is that some of the operations can be done at a higher level with C because lex and yacc take care of many of the details. David S. Cargo (DSCARGO@CIM-VAX.HONEYWELL.COM) From dscargo@cim-vax.honeywell.com Fri May 19 09:15:53 1989 Message-Id: <8905191615.AA28127@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA28127; Fri, 19 May 89 09:15:53 MST Date: 19 May 89 10:39:00 CST From: "DAVE CARGO" Subject: macro processor wanted To: "icon-group" Just in an effort to save some programming time, I was wondering if anybody had an Icon program that was a functioning macro processor. The capabilities I'm looking for are modest; if somebody has developed a macro processor, it will probably do more than what I am looking for. The caabilities are to read a definition file, then read an input file making simple substitutions and writing an output file. The input file would look something like a set of lines of the form replacement text The replacement text would be limited to one line, but the line could be long. The token would be characters not including a ">" character. The processing would be to read the input file and replace any instances of with the corresponding replacement text. (The "<" and ">" are literal characters that actually appear in the input stream; I'm not using them as metacharacters.) If I don't get any response, I'll write the program and be willing to make it available to the Icon Program Library. dsc From dscargo@cim-vax.honeywell.com Wed May 31 08:44:15 1989 Message-Id: <8905311544.AA21349@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA21349; Wed, 31 May 89 08:44:15 MST Date: 31 May 89 10:38:00 CST From: "DAVE CARGO" Subject: Null output for write To: "icon-group" I ran the following test program on VMS (Icon V7.0) procedure main() file := [&output, &null] every write(!file, "There it goes!") return end I got "There it goes!" twice. Is there any "Icon standard" way of directing output to a "null" device? My context was a program where sometimes I wanted to generate output and sometimes not. Rather than using an if statement, I thought about an output that sometimes indicated a file and sometimes indicated a null device. Does Icon have such a thing? dsc From ralph Wed May 31 08:53:04 1989 Date: Wed, 31 May 89 08:53:04 MST From: "Ralph Griswold" Message-Id: <8905311553.AA22189@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA22189; Wed, 31 May 89 08:53:04 MST To: dscargo@cim-vax.honeywell.com Subject: Re: Null output for write Cc: icon-group In-Reply-To: <8905311544.AA21349@megaron.arizona.edu> A null argument to write() defaults to the empty string. Most systems have some name or device that serves a to dump output without actually writing it. Open this "file" and use it like any other. E.g. nullfile := open("/dev/null","w") . . . write(nullfile, ...) Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From unocc07@zeus.unl.edu Wed May 31 16:26:01 1989 Message-Id: <8905312326.AA19953@megaron.arizona.edu> Received: from [129.93.1.10] by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA19953; Wed, 31 May 89 16:26:01 MST Date: 31 May 89 18:23:00 CST From: "Dave Caplinger" Subject: Re: Null output for write To: "icon-group" (Ralph Griswold writes:) >Most systems have some name or device that serves a to dump output without >actually writing it. Open this "file" and use it like any other. E.g. > > nullfile := open("/dev/null","w") > . > . > . > write(nullfile, ...) > > Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 > +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph The VMS equivilant for the UNIX /dev/null device is device NLA0:, which may be helpfull to you... On another note; I recently got a flyer about ProIcon, which apparently is the first commercial implementation of Icon, available for the Mac. Since the flyer was not particularly descriptive (the picture looked like it was taken from the MPW version of Icon), can anyone describe the benefits/differences/etc of ProIcon? Does it allow access to the toolboxes (which the MPW version does not)? Is it compiled (just being able to make "stand-alone" applications is sufficient for me..)? Any info would be greatly appreciated! -/ Dave Caplinger /------------------+----------------------------------- Microcomputer Specialist | Internet: unocc07@zeus.unl.edu "Computing and Data Communications" | UUCP: uunet!btni!unocss!dent University of Nebraska at Omaha | Bitnet: UNOCC07@UNOMA1 Omaha, NE 68182 | or dc3a+@andrew.cmu.edu From att!ihlpb!nevin1 Wed May 31 16:35:27 1989 Date: Wed, 31 May 89 16:35:27 MST Message-Id: <8905312335.AA20295@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA20295; Wed, 31 May 89 16:35:27 MST From: ihlpb!nevin1 (Nevin J Liber +1 312 979 4751) To: att!arizona!icon-group Cc: "DAVE CARGO" Subject: Re: Null output for write Dave Cargo (dscargo@cim-vax.HONEYWELL.COM) writes: >procedure main() > file := [&output, &null] > every write(!file, "There it goes!") > return >end >I got "There it goes!" twice. Is there any "Icon standard" way of directing >output to a "null" device? This isn't exactly the same (I will point out the difference later) as directing output to a "null" device (such as /dev/null in Unix(R)), but changing every write(!file, "There it goes!") to every write(\!file, "There it goes!") should accomplish what you want. Here is what happens: if the value of "!file" is "&null", the expression "\!file" fails. Since failure is inherited, the write fails, and no output is produced. Because failure gets inherited, this will behave differently than redirecting to a "null" device when there is a side effect in a future parameter to this particular call to write(), when the write() is a parameter to another function, etc. NEVIN ":-)" LIBER AT&T Bell Laboratories nevin1@ihlpb.ATT.COM (312) 979-4751 From dscargo@cim-vax.honeywell.com Thu Jun 1 10:11:28 1989 Message-Id: <8906011711.AA09670@megaron.arizona.edu> Received: from CIM-VAX.HONEYWELL.COM by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA09670; Thu, 1 Jun 89 10:11:28 MST Date: 1 Jun 89 12:00:00 CST From: "DAVE CARGO" Subject: null output in Icon To: "icon-group" Thanks for the responses to my question about null output devices for Icon write statements. The reason I wanted to do it in Icon instead of opening a system-specific file is that I wanted the program to be portable among Icon implementations. Since there isn't a &nullout (only &output and &errout), I wanted to find some way to achieve the same result within Icon without using nonportable code. The "write(\file,...)" approach meets my needs. dsc From ralph Sat Jun 3 05:57:54 1989 Date: Sat, 3 Jun 89 05:57:54 MST From: "Ralph Griswold" Message-Id: <8906031257.AA07236@megaron.arizona.edu> Received: by megaron.arizona.edu (5.59-1.7/15) id AA07236; Sat, 3 Jun 89 05:57:54 MST To: icon-group Subject: ProIcon There have been several questions in recent mail about the new "ProIcon" implementation of Icon for the Macintosh. Here's some information. ProIcon is an extended and enhanced implementation of Version 7.5 of Icon. It runs on the Macintosh as a "stand-alone" application like most other Macintosh applications -- it does not require MPW. The ProIcon application, which uses the standard Macintosh interface, contains an editor and has menus for compiling and running Icon programs, setting options, managing windows, and so forth -- as well as providing the usual services you expect on the Mac, such as printing and clipboard facilities. You can can create, run, test, edit and debug programs Icon programs without leaving the ProIcon application. So far as the ProIcon language itself is concerned, it has everything in Version 7.5 plus several enhancements, some of a general nature and some specifically for the Mac environment. It has function tracing (in addition to the usual procedure tracing), an optional termination dump, optional use of the Macintosh International String Comparison system, and several dozen new functions. Many of the functions provide the tools necessary for a running Icon program to communicate with users -- dialog boxes, screen manipulation, window functions, and so forth. ProIcon, however, does not have graphic capabilities (Quickdraw) or access to the Toolbox. Icon programs compiled by ProIcon also run as stand-alone applications. They need a run-time system, which is provided, but this is essentially invisible. Icon programs compiled by ProIcon can be given to others, along with the run-time system; there are no licensing requirements or royalties for such distribution. ProIcon will run on any Macintosh except those with 64K ROM. It needs at least 400 KB of free memory (1MB RAM is recommended), and System Version 4.1 or higher. ProIcon is marketed by Catspaw, Inc. P.O. Box 1123 Salida, CO 81201-1123 (719) 539-3884 Contact Catspaw for more information. Ralph Griswold / Dept of Computer Science / Univ of Arizona / Tucson, AZ 85721 +1 602 621 6609 ralph@Arizona.EDU uunet!arizona!ralph From naucse!sbw Mon Jun 12 21:40:18 1989 Received: by megaron.arizona.edu (5.59-1.7/15) id AA23692; Mon, 12 Jun 89 21:40:18 MST Message-Id: <8906130306.AA20647@naucse> Date: Mon, 12 Jun 89 20:06:40 MST X-Mailer: Mail User's Shell (6.5 4/17/89) From: naucse!naucse!sbw (Steve Wampler) To: arizona!icon-group Subject: Icon with curses? I have an application where I'd like to use curses from an Icon program. Has anyone built a personalized interpreter for Icon that includes curses? -- Steve Wampler {....!arizona!naucse!sbw} From shafto@eos.arc.nasa.gov Tue Jun 13 09:26:40 1989 Received: from eos.arc.nasa.gov by megaron.arizona.edu (5.59-1.7/15) via SMTP id AA26034; Tue, 13 Jun 89 09:26:40 MST Received: Tue, 13 Jun 89 09:25:05 PDT by eos.arc.nasa.gov (5.59/1.2) Date: Tue, 13 Jun 89 09:25:05 PDT From: Michael Shafto Message-Id: <8906131625.AA24006@eos.arc.nasa.gov> To: icon-group@arizona.edu, naucse!naucse!sbw@arizona.edu Subject: Re: Icon with curses? Cc: shafto@EOS.ARC.NASA.GOV Steve -- You're probably aware of Gimpel's insult generator in the orange SNOBOL4 book -- Program 17.1 PHRASE, pp. 377ff. Mike