[comp.lang.icon] criticism of icon

lakshmin@atanasoff.cs.iastate.edu (Lakshminarayana Rudrabhatla) (09/08/89)

procedure main()

	words:=table()
	line_no:=0
	while line:=read() do {
		line_no +:=1
		write(left(line_no,6),left(line,40))
		line:=map(line)
		i:=1
		while j:=upto(&lcase,line,i) do {
		i:=many(&lcase,line,j)
		if *line[i:j] >= 3
		then {if   \words[line[i:j]]       #line 14
	              then insert(words[line[i:j]],line_no)    #line 15
		      else {words[line[i:j]]:=set()    #line 16
		            insert(words[line[i:j]], line_no)   #line 17 
			  }
                     }
		}
        }

  	words:=sort(words)
	i:=0
	while pair:=words[i +:=1] do  {
	   writes(left(pair[1],10),":")
	   s:=!pair[2]
	   pair[2]:=delete(pair[2],!pair[2])
           every s ||:= ", " ||!pair[2]
	   write(s)
	   }
	end

---------------------------------------------------------
question:
   
   in lines 14 thru 17 of the above program i had to implicitly
   declare the type of assigned value of table "words"
   as set(){ref: line#16} before i could perform
   the insert op. in line #15.
   this problem arose because &null would'nt coerce automatically
   to set(). this inspite of the claim that icon is dynamically typed.
   As a user, my "natural" impression was to assume that &null could
   represent an set() or "" or [] , as the case may be, since
   this facilitates easier and logical manipulation of the
   assigned value part of the structure "table" in general.
   
   does anyone see any problems with modifying the language to allow
   coercion of &null to set() or "" or [], as the case maybe depending
   upon the type of operation being performed on the assigned part of
   the structure "table".

wgg@JUNE.CS.WASHINGTON.EDU (William Griswold) (09/09/89)

>Date: 8 Sep 89 16:43:55 GMT
>From: dino!atanasoff!atanasoff.cs.iastate.edu!lakshmin@uunet.uu.net  (Lakshminarayana Rudrabhatla)
>Organization: Iowa State U. Computer Science Department, Ames, IA
>Subject: criticism of icon
>Sender: icon-group-request@arizona.edu
>To: icon-group@arizona.edu
>Errors-To: icon-group-errors@arizona.edu
>
>
... program ...
>---------------------------------------------------------
>question:
>   
>   in lines 14 thru 17 of the above program i had to implicitly
>   declare the type of assigned value of table "words"
>   as set(){ref: line#16} before i could perform
>   the insert op. in line #15.
>   this problem arose because &null would'nt coerce automatically
>   to set(). this inspite of the claim that icon is dynamically typed.
>   As a user, my "natural" impression was to assume that &null could
>   represent an set() or "" or [] , as the case may be, since
>   this facilitates easier and logical manipulation of the
>   assigned value part of the structure "table" in general.
>   
>   does anyone see any problems with modifying the language to allow
>   coercion of &null to set() or "" or [], as the case maybe depending
>   upon the type of operation being performed on the assigned part of
>   the structure "table".
>

In language design there is a constant tension between flexibility and
protecting the programmer from himself or herself.  One of the design
decisions of Icon was that if the programmer hasn't said what a value is,
that it is null.  If this weren't the case, every time I used an uninitialized
variable (and I had intended it be initialzed with some special value, but had
forgotten to do it) it would default to something else (perhaps close), and 
it could be very difficult to debug.

I can personally testify that this feature of Icon has saved me hours of
debugging time.  When Icon terminates on an error ``Integer expected,
offending value: null'', I know what has gone wrong.  However, if my
porgram terminates normally, and I find the integer result is off by
17, I don't quite know where to begin to look.  This feature of
Icon is especially valuable for larger programs, in which it is difficult
to keep track of everything that is going on, or perhaps many people are
writing code.

Also, it is not entirely clear from the code you provided whether the value
should be a set or table, since table has insert as well (although it
wouldn't be doing anything incredibly reasonable here).  In fact, you'll 
run into the same problem whenever you have a polymorphic operation that 
isn't binary symmetric.  If default behavior becomes very complicated, it
is better to do without. 

Actually, there *is* a more concise solution to your problem.  Here is the
code that you annotated in your previous example, and a shorter version.

>		then {if   \words[line[i:j]]       #line 14
>	              then insert(words[line[i:j]],line_no)    #line 15
>		      else {words[line[i:j]]:=set()    #line 16
>		            insert(words[line[i:j]], line_no)   #line 17 
>			  }
>                     }

		then { /words[line[i:j]] := set()        #line 14
	              insert(words[line[i:j]],line_no)    #line 17
                     }

It may not be automatic, but it is only one line longer than the solution
you'd like to have.  You can actually do it in one line, but it isn't
pretty.

					Bill Griswold

sbw@naucse.UUCP (Steve Wampler) (09/09/89)

On Sep 8 at 11:42, William Griswold writes:
} 		then { /words[line[i:j]] := set()        #line 14
} 	              insert(words[line[i:j]],line_no)    #line 17
}                      }
} 
} It may not be automatic, but it is only one line longer than the solution
} you'd like to have.  You can actually do it in one line, but it isn't
} pretty.
} 
Is too:

		words[line[i:j]] := insert(\words[line[i:j]]|set(), line_no)

well, maybe if we do the assignment:  word := line[i:j] first, then:

		words[word] := insert(\words[word]|set(), line_no)

well, maybe if... nevermind.

-- 
	Steve Wampler
	{....!arizona!naucse!sbw}