Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
Icon (programming language)
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
===Goal-directed execution=== One of the key concepts in SNOBOL was that its functions returned the "success" or "failure" as primitives of the language rather than using [[magic number (programming)|magic numbers]] or other techniques.{{sfn|Griswold|Griswold|2002|p=4}}{{sfn|Tratt|2010|p=74}} For example, a function that returns the position of a substring within another string is a common routine found in most language [[runtime system]]s. In [[JavaScript]] to find the position of the word "World" within a [["Hello, World!" program]] would be accomplished with {{code|position {{=}} "Hello, World".indexOf("World")|icon}}, which would return 7 in the variable {{code|position}}. If one instead asks for the {{code|position {{=}} "Hello, World".indexOf("Goodbye")|icon}} the code will "fail", as the search term does not appear in the string. In JavaScript, as in most languages, this will be indicated by returning a magic number, in this case -1.<ref>{{cite web |url=https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/indexOf |title=Array.prototype.indexOf() |website=MDN Web Docs|date=27 June 2023 }}</ref> In SNOBOL a failure of this sort returns a special value, {{code|&fail}}. SNOBOL's syntax operates directly on the success or failure of the operation, jumping to labelled sections of the code without having to write a separate test. For instance, the following code prints "Hello, world!" five times:<ref name=lane>{{cite web |url=https://try-mts.com/snobol-introduction/ |title= SNOBOL - Introduction |website=Try MTS |date=26 July 2015 |first=Rupert |last=Lane}}</ref> <syntaxhighlight lang=snobol> * SNOBOL program to print Hello World I = 1 LOOP OUTPUT = "Hello, world!" I = I + 1 LE(I, 5) : S(LOOP) END </syntaxhighlight> To perform the loop, the less-than-or-equal operator, {{code|LE}}, is called on the index variable I, and if it {{code|S}}ucceeds, meaning I is less than 5, it branches to the named label {{code|LOOP}} and continues.<ref name=lane/> Icon retained the concept of flow control based on success or failure but developed the language further. One change was the replacement of the labelled {{code|GOTO}}-like branching with block-oriented structures in keeping with the [[structured programming]] style that was sweeping the computer industry in the late 1960s.{{sfn|Griswold|Griswold|1993|p=53}} The second was to allow "failure" to be passed along the call chain so that entire blocks will succeed or fail as a whole. This is a key concept of the Icon language. Whereas in traditional languages one would have to include code to test the success or failure based on [[Boolean logic]] and then branch based on the outcome, such tests and branches are inherent to Icon code and do not have to be explicitly written.{{sfn|Tratt|2010|p=73}} For instance, consider this bit of code written in the [[Java programming language]]. It calls the function {{code|read()}} to read a character from a (previously opened) file, assigns the result to the variable {{code|a}}, and then {{code|write}}s the value of {{code|a}} to another file. The result is to copy one file to another. {{code|read}} will eventually run out of characters to read from the file, potentially on its very first call, which would leave {{code|a}} in an undetermined state and potentially cause {{code|write}} to cause a [[null pointer exception]]. To avoid this, {{code|read}} returns the special value {{code|EOF}} (end-of-file) in this situation, which requires an explicit test to avoid {{code|write}}ing it: <syntaxhighlight lang="java"> while ((a = read()) != EOF) { write(a); } </syntaxhighlight> In contrast, in Icon the {{code|read()}} function returns a line of text or {{code|&fail}}. {{code|&fail}} is not simply an analog of {{code|EOF}}, as it is explicitly understood by the language to mean "stop processing" or "do the fail case" depending on the context. The equivalent code in Icon is:{{sfn|Tratt|2010|p=74}} <syntaxhighlight lang="icon"> while a := read() do write(a) </syntaxhighlight> This means, "as long as read does not fail, call write, otherwise stop".{{sfn|Tratt|2010|p=74}} There is no need to specify a test against the magic number as in the Java example, this is implicit, and the resulting code is simplified. Because success and failure are passed up through the call chain, one can embed function calls within others and they stop when the nested function call fails. For instance, the code above can be reduced to:{{sfn|Griswold|1996|p=2.1}} <syntaxhighlight lang="icon"> while write(read()) </syntaxhighlight> In this version, if the {{code|read}} call fails, the {{code|write}} call fails, and the {{code|while}} stops.{{sfn|Griswold|1996|p=2.1}} Icon's branching and looping constructs are all based on the success or failure of the code inside them, not on an arbitrary Boolean test provided by the programmer. {{code|if}} performs the {{code|then}} block if its "test" returns a value, and performs the {{code|else}} block or moves to the next line if it returns {{code|&fail}}. Likewise, {{code|while}} continues calling its block until it receives a fail. Icon refers to this concept as '''goal-directed execution'''.{{sfn|Griswold|1996|p=1}} It is important to contrast the concept of success and failure with the concept of an [[Exception handling|exception]]; exceptions are unusual situations, not expected outcomes. Fails in Icon are expected outcomes; reaching the end of a file is an expected situation and not an exception. Icon does not have exception handling in the traditional sense, although fail is often used in exception-like situations. For instance, if the file being read does not exist, {{code|read}} fails without a special situation being indicated.{{sfn|Tratt|2010|p=74}} In traditional language, these "other conditions" have no natural way of being indicated; additional magic numbers may be used, but more typically exception handling is used to "throw" a value. For instance, to handle a missing file in the Java code, one might see: <syntaxhighlight lang="java"> try { while ((a = read()) != EOF) { write(a); } } catch (Exception e) { // something else went wrong, use this catch to exit the loop } </syntaxhighlight> This case needs two comparisons: one for EOF and another for all other errors. Since Java does not allow exceptions to be compared as logic elements, as under Icon, the lengthy {{code|try/catch}} syntax must be used instead. Try blocks also impose a performance penalty even if no exception is thrown, a [[distributed cost]] that Icon normally avoids. Icon uses this same goal-directed mechanism to perform traditional Boolean tests, although with subtle differences. A simple comparison like {{code|if a < b then write("a is smaller than b")|icon}} does not mean, "if the conditional expression evaluation results in or returns a true value" as they would under most languages; instead, it means something more like, "if the conditional expression succeeds and does not fail". In this case, the {{code|<}} operator succeeds if the comparison is true. The {{code|if}} calls its {{code|then}} clause if the expression succeeds, and either the {{code|else}} (if present) or the next line if it fails. The result is similar to the traditional if/then seen in other languages, the {{code|if}} performs {{code|then}} if {{code|a}} is less than {{code|b}}. The subtlety is that the same comparison expression can be placed anywhere, for instance: <syntaxhighlight lang="icon"> write(a < b) </syntaxhighlight> Another difference is that the {{code|<}} operator returns its second argument if it succeeds, which in this example will result in the value of {{code|b}} being written if it is larger than {{code|a}}, otherwise nothing is written. As this is not a test ''per se'', but an operator that returns a value, they can be strung together allowing things like {{code|if a < b < c}},{{sfn|Griswold|1996|p=2.1}} a common type of comparison that in most languages must be written as a conjunction of two inequalities like {{code|if (a < b) && (b < c)}}. A key aspect of goal-directed execution is that the program may have to rewind to an earlier state if a procedure fails, a task known as ''backtracking''. For instance, consider code that sets a variable to a starting location and then performs operations that may change the value - this is common in string scanning operations for instance, which will advance a cursor through the string as it scans. If the procedure fails, it is important that any subsequent reads of that variable return the original state, not the state as it was being internally manipulated. For this task, Icon has the ''reversible assignment'' operator, {{code|<-}}, and the ''reversible exchange'', {{code|<->}}. For instance, consider some code that is attempting to find a pattern string within a larger string: <syntaxhighlight lang="icon"> { (i := 10) & (j := (i < find(pattern, inString))) } </syntaxhighlight> This code begins by moving {{code|i}} to 10, the starting location for the search. However, if the {{code|find}} fails, the block will fail as a whole, which results in the value of {{code|i}} being left at 10 as an undesirable [[Side effect (computer science)|side effect]]. Replacing {{code|i :{{=}} 10}} with {{code|i <- 10}} indicates that {{code|i}} should be reset to its previous value if the block fails. This provides an analog of [[Atomic commit|atomicity]] in the execution.
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)