home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1992 #27 / NN_1992_27.iso / spool / comp / lang / modula2 / 1394 < prev    next >
Encoding:
Text File  |  1992-11-15  |  15.4 KB  |  511 lines

  1. Newsgroups: comp.lang.modula2
  2. Path: sparky!uunet!math.fu-berlin.de!news.belwue.de!theorie!titania.mathematik.uni-ulm.de!borchert
  3. From: borchert@titania.mathematik.uni-ulm.de (Andreas Borchert)
  4. Subject: Re: Oberon vs Modula-2 (Re: mail delivery error)
  5. Message-ID: <1992Nov16.080647.26783@informatik.uni-ulm.de>
  6. Sender: usenet@informatik.uni-ulm.de (Name for nntp-posting)
  7. Nntp-Posting-Host: titania.mathematik.uni-ulm.de
  8. Organization: University of Ulm, SAI
  9. References: <5897@balrog.ctron.com> <1992Nov11.102409.12183@jyu.fi> <1992Nov13.100154.6167@informatik.uni-ulm.de> <1992Nov13.130852.22775@jyu.fi>
  10. Date: Mon, 16 Nov 92 08:06:47 GMT
  11. Lines: 498
  12.  
  13. In article <1992Nov13.130852.22775@jyu.fi>, sakkinen@jyu.fi (Markku Sakkinen) writes:
  14. > >> But set types have always been sadly crippled in
  15. > >> Wirth's languages:  Pascal implementers are not required to support
  16. > >> even the the full CHAR type as the base type for SET OF CHAR,
  17. > >> not to speak of true SET OF INTEGER.  Fully-fledged set types could often
  18. > >> be useful abstractions in programming.
  19. > >
  20. > >Wirth's aim was always to avoid putting algorithms into the language
  21. > >which could be expressed by the language itself. Having a basic set type,
  22. > >you are able to build up arbitrary set types which work efficiently.
  23. > These extremely restricted set types could well be replaced by
  24. > PACKED ARRAY [ ... ] OF BOOLEAN.  It's the set types with large
  25. > base types that are difficult and tedious for programmers to write
  26. > themselves.  Imagine that arrays were restricted to base types
  27. > of cardinality no greater than 128, and you would have to build up
  28. > larger arrays yourself.
  29.  
  30. To prove the easiness of large set types in Oberon I've attached my
  31. Sets module which accepts arbitrary ARRAY OF SETs.
  32.  
  33. > >> I have read somewhere that the parameter modes were variable vs. constant
  34. > >> in an early version of Pascal.  That would have been much better
  35. > >> than the current by-value vs. by-reference distinction (which should be left
  36. > >> as an implementation issue)!
  37. > >
  38. > >The choice between by-value and by-reference as an implementation issue? 
  39. > >Sounds not reasonable -- probably I've missed your point.
  40. > Let me elaborate.  The important conceptual dichotomy in parameters
  41. > is whether the called procedure can modify the actual parameter
  42. > (in the caller's context) or not.  In the former case (variable)
  43. > it is necessary to pass a reference to the actual parameter,
  44. > or do copy in - copy out.  In the latter case (constant), the parameter
  45. > can be passed either by reference or by value,
  46. > without any difference in the semantics.
  47. > Value parameters as in Algol 60, Pascal, Modula-2, etc. bundle
  48. > the choices by not allowing constant parameters to be passed
  49. > by reference.  The gain from this approach is that the programmer
  50. > automatically gets a copy that can be modified without affecting
  51. > the actual parameter.  It was probably quite nice in the Algol 60 days,
  52. > when variables were mostly single integers or reals (and the other
  53. > alternative was the formidable call-by-name).
  54. > The loss is that the copy is done even when
  55. > it is not needed, and with large parameter objects it's a big loss
  56. > (imagine recursive calls with a 1000 x 1000 array parameter).
  57. > It seems to be common practice that programmers declare very
  58. > large parameters as VAR even in cases where they should absolutely
  59. > not be modified -- only to avoid the performance penalty.
  60.  
  61. Agreed, programmers shouldn't be enforced to use VAR-parameters
  62. for reasons of efficiency only. But, even with the semantics of
  63. Oberon or Modula-2, it's not to difficult for the compiler to
  64. detect that your 1000 x 1000 array isn't modified and, thus,
  65. doesn't need to be copied.
  66.  
  67. Usually, the calling procedure passes a reference to the array onto
  68. the stack in both cases and the called procedure then makes a copy
  69. of the array if you have call-by-value and your array parameter
  70. is subject to changes.
  71.  
  72. Your point (hopefully I understand now your point :-) is that this
  73. decision can be eased for the compiler by replacing call-by-value by
  74. passing of readonly parameters. While this is not really necessary
  75. to achieve the efficiency goal, I believe it's a worthy feature because
  76. it would help to make the code more readable.
  77.  
  78. And now the promised attachment. It's still in early Oberon style,
  79. i.e. separated DEFINITION and MODULE.
  80.  
  81. #!/bin/sh
  82. # This is a shell archive (produced by shar 3.49)
  83. # To extract the files from this archive, save it to a file, remove
  84. # everything above the "!/bin/sh" line above, and type "sh file_name".
  85. #
  86. # made 11/16/1992 07:42 UTC by borchert@mathematik.uni-ulm.de
  87. # Source directory /export/home/borchert/tmp/48
  88. #
  89. # existing files will NOT be overwritten unless -c is specified
  90. #
  91. # This shar contains:
  92. # length  mode       name
  93. # ------ ---------- ------------------------------------------
  94. #   3205 -r--r--r-- Sets.3
  95. #   1337 -rw-rw-r-- Sets.od
  96. #   4661 -rw-rw-r-- Sets.om
  97. #
  98. # ============= Sets.3 ==============
  99. if test -f 'Sets.3' -a X"$1" != X"-c"; then
  100.     echo 'x - skipping Sets.3 (File already exists)'
  101. else
  102. echo 'x - extracting Sets.3 (Text)'
  103. sed 's/^X//' << 'SHAR_EOF' > 'Sets.3' &&
  104. .\" --------------------------------------
  105. .\" Oberon System Documentation   AFB 8/90
  106. .\" (c) University of Ulm, SAI, D-7900 Ulm
  107. .\" --------------------------------------
  108. .de Pg
  109. .nf
  110. .ie t \{\
  111. .    sp 0.3v
  112. .    ps 9
  113. .    ft CW
  114. .\}
  115. .el .sp 1v
  116. ..
  117. .de Pe
  118. .ie t \{\
  119. .    ps
  120. .    ft P
  121. .    sp 0.3v
  122. .\}
  123. .el .sp 1v
  124. .fi
  125. ..
  126. .TH Sets 3 "Oberon System"
  127. .SH NAME
  128. Sets \- operations for sets of arbitrary length
  129. .SH SYNOPSIS
  130. .Pg
  131. CONST setsize = MAX(SET) + 1;
  132. .sp 0.7
  133. TYPE CharSet = ARRAY ORD(MAX(CHAR)) DIV setsize OF SET;
  134. .sp 0.7
  135. VAR lengthError: Events.EventType;
  136. .sp 0.7
  137. PROCEDURE InitSet(VAR set: ARRAY OF SET);
  138. .sp 0.3
  139. PROCEDURE Complement(VAR set: ARRAY OF SET);
  140. .sp 0.3
  141. PROCEDURE Union(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  142. PROCEDURE Difference(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  143. PROCEDURE Intersection(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  144. PROCEDURE SymDifference(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  145. .sp 0.3
  146. PROCEDURE In(VAR set: ARRAY OF SET; i: LONGINT) : BOOLEAN;
  147. PROCEDURE CharIn(VAR charset: CharSet; ch: CHAR) : BOOLEAN;
  148. PROCEDURE Equal(set1, set2: ARRAY OF SET) : BOOLEAN;
  149. .sp 0.3
  150. PROCEDURE Incl(VAR set: ARRAY OF SET; i: LONGINT);
  151. PROCEDURE Excl(VAR set: ARRAY OF SET; i: LONGINT);
  152. PROCEDURE InclChar(VAR charset: CharSet; ch: CHAR);
  153. PROCEDURE ExclChar(VAR charset: CharSet; ch: CHAR);
  154. .sp 0.3
  155. PROCEDURE Subset(set1, set2: ARRAY OF SET) : BOOLEAN;
  156. PROCEDURE Card(set: ARRAY OF SET) : INTEGER;
  157. .Pe
  158. .SH DESCRIPTION
  159. .I Sets
  160. implements set operations for character sets and
  161. sets of arbitrary length.
  162. .I setsize
  163. defines the number of bits per
  164. .B SET
  165. type.
  166. .I CharSet
  167. is an array of
  168. .B SET
  169. sufficient for characters.
  170. .I InitSet
  171. initializes
  172. .I set
  173. to the empty set.
  174. .PP
  175. Following set operators are implemented:
  176. .sp
  177. .TS
  178. l l.
  179. set operator    set operation
  180. _
  181. unary \fB-\fP    \fIComplement\fP
  182. \fB+\fP    \fIUnion\fP
  183. \fB-\fP    \fIDifference\fP
  184. \fB*\fP    \fIIntersection\fP
  185. \fB/\fP    \fISymDifference\fP
  186. \fBIN\fP    \fIIn\fP and \fICharIn\fP
  187. \fB=\fP    \fIEqual\fP
  188. \fBINCL\fP    \fIIncl\fP and \fIInclChar\fP
  189. \fBEXCL\fP    \fIExcl\fP and \fIExclChar\fP
  190. .TE
  191. .PP
  192. \fISubset\fP returns \fBTRUE\fP iff
  193. \fIset1\fP is contained in \fIset2\fP.
  194. \fICard\fP returns the cardinality
  195. (number of elements) of \fIset\fP.
  196. .SH DIAGNOSTICS
  197. \fISets\fP
  198. raises \fIlengthError\fP with priority \fIPriorities.assertions\fP
  199. if the length of \fIresult\fP is less than
  200. the length of \fIset1\fP or \fIset2\fP.
  201. .SH "SEE ALSO"
  202. .TS
  203. lfI l.
  204. Assertions(3)    error handling for length errors
  205. .TE
  206. .\" ---------------------------------------------------------------------------
  207. .\" $Id: Sets.3,v 1.5 91/11/25 09:15:53 borchert Exp $
  208. .\" ---------------------------------------------------------------------------
  209. .\" $Log:    Sets.3,v $
  210. .\" Revision 1.5  91/11/25  09:15:53  borchert
  211. .\" lengthError is now handled by Assertions
  212. .\" 
  213. .\" Revision 1.4  1991/11/12  08:43:40  borchert
  214. .\" Events.EventNumber replaced by Events.EventType
  215. .\"
  216. .\" Revision 1.3  1991/06/21  15:32:34  borchert
  217. .\" minor fix
  218. .\"
  219. .\" Revision 1.2  91/06/18  13:57:08  borchert
  220. .\" new operators added
  221. .\" 
  222. .\" Revision 1.1  90/08/31  17:02:19  borchert
  223. .\" Initial revision
  224. .\" 
  225. .\" ---------------------------------------------------------------------------
  226. SHAR_EOF
  227. chmod 0444 Sets.3 ||
  228. echo 'restore of Sets.3 failed'
  229. Wc_c="`wc -c < 'Sets.3'`"
  230. test 3205 -eq "$Wc_c" ||
  231.     echo 'Sets.3: original size 3205, current size' "$Wc_c"
  232. fi
  233. # ============= Sets.od ==============
  234. if test -f 'Sets.od' -a X"$1" != X"-c"; then
  235.     echo 'x - skipping Sets.od (File already exists)'
  236. else
  237. echo 'x - extracting Sets.od (Text)'
  238. sed 's/^X//' << 'SHAR_EOF' > 'Sets.od' &&
  239. (* Oberon Library      -  UNIX System V  -      AFB 9/89 *)
  240. (* (c) University of Ulm, Sektion Informatik, D-7900 Ulm *)
  241. X
  242. DEFINITION Sets;
  243. X
  244. X   IMPORT Events;
  245. X
  246. X   CONST
  247. X      setsize = MAX(SET) + 1;
  248. X
  249. X   TYPE
  250. X      CharSet = ARRAY ORD(MAX(CHAR)) DIV setsize OF SET;
  251. X
  252. X   VAR
  253. X      lengthError: Events.EventType;
  254. X     (* raised with Priorites.assertions if the length of
  255. X        the result is less than its parameters
  256. X     *)
  257. X
  258. X   PROCEDURE InitSet(VAR set: ARRAY OF SET);
  259. X
  260. X   PROCEDURE Complement(VAR set: ARRAY OF SET);
  261. X
  262. X   PROCEDURE In(VAR set: ARRAY OF SET; i: LONGINT) : BOOLEAN;
  263. X
  264. X   PROCEDURE Incl(VAR set: ARRAY OF SET; i: LONGINT);
  265. X   PROCEDURE Excl(VAR set: ARRAY OF SET; i: LONGINT);
  266. X
  267. X   PROCEDURE CharIn(VAR charset: CharSet; ch: CHAR) : BOOLEAN;
  268. X
  269. X   PROCEDURE InclChar(VAR charset: CharSet; ch: CHAR);
  270. X   PROCEDURE ExclChar(VAR charset: CharSet; ch: CHAR);
  271. X
  272. X   PROCEDURE Intersection(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  273. X   PROCEDURE SymDifference(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  274. X   PROCEDURE Union(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  275. X   PROCEDURE Difference(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  276. X
  277. X   PROCEDURE Equal(set1, set2: ARRAY OF SET) : BOOLEAN;
  278. X   PROCEDURE Subset(set1, set2: ARRAY OF SET) : BOOLEAN;
  279. X
  280. X   PROCEDURE Card(set: ARRAY OF SET) : INTEGER;
  281. X
  282. END Sets.
  283. SHAR_EOF
  284. chmod 0664 Sets.od ||
  285. echo 'restore of Sets.od failed'
  286. Wc_c="`wc -c < 'Sets.od'`"
  287. test 1337 -eq "$Wc_c" ||
  288.     echo 'Sets.od: original size 1337, current size' "$Wc_c"
  289. fi
  290. # ============= Sets.om ==============
  291. if test -f 'Sets.om' -a X"$1" != X"-c"; then
  292.     echo 'x - skipping Sets.om (File already exists)'
  293. else
  294. echo 'x - extracting Sets.om (Text)'
  295. sed 's/^X//' << 'SHAR_EOF' > 'Sets.om' &&
  296. (* Oberon Library      -  UNIX System V  -      AFB 9/89 *)
  297. (* (c) University of Ulm, Sektion Informatik, D-7900 Ulm *)
  298. X
  299. MODULE Sets;
  300. X
  301. X   IMPORT Assertions, Events, Priorities;
  302. X
  303. X   CONST
  304. X      setsize = MAX(SET) + 1;
  305. X
  306. X   TYPE
  307. X      CharSet = ARRAY ORD(MAX(CHAR)) DIV setsize OF SET;
  308. X
  309. X   VAR
  310. X      lengthError: Events.EventType;
  311. X     (* raised with Priorites.assertions if the length of
  312. X        the result is less than its parameters
  313. X     *)
  314. X
  315. X   PROCEDURE LengthError(procname: ARRAY OF CHAR);
  316. X   BEGIN
  317. X      Assertions.Raise(NIL, lengthError, procname, "set lengths are different");
  318. X   END LengthError;
  319. X
  320. X   PROCEDURE InitSet(VAR set: ARRAY OF SET);
  321. X      VAR i: LONGINT;
  322. X   BEGIN
  323. X      i := 0;
  324. X      WHILE i < LEN(set) DO
  325. X     set[i] := {}; INC(i);
  326. X      END;
  327. X   END InitSet;
  328. X
  329. X   PROCEDURE Complement(VAR set: ARRAY OF SET);
  330. X      VAR i: LONGINT;
  331. X   BEGIN
  332. X      i := 0;
  333. X      WHILE i < LEN(set) DO
  334. X     set[i] := - set[i]; INC(i);
  335. X      END;
  336. X   END Complement;
  337. X
  338. X   PROCEDURE In(VAR set: ARRAY OF SET; i: LONGINT) : BOOLEAN;
  339. X   BEGIN
  340. X      RETURN (i MOD setsize) IN set[i DIV setsize]
  341. X   END In;
  342. X
  343. X   PROCEDURE Incl(VAR set: ARRAY OF SET; i: LONGINT);
  344. X   BEGIN
  345. X      INCL(set[i DIV setsize], i MOD setsize);
  346. X   END Incl;
  347. X
  348. X   PROCEDURE Excl(VAR set: ARRAY OF SET; i: LONGINT);
  349. X   BEGIN
  350. X      EXCL(set[i DIV setsize], i MOD setsize);
  351. X   END Excl;
  352. X
  353. X   PROCEDURE CharIn(VAR charset: CharSet; ch: CHAR) : BOOLEAN;
  354. X   BEGIN
  355. X      RETURN (ORD(ch) MOD setsize) IN charset[ORD(ch) DIV setsize]
  356. X   END CharIn;
  357. X
  358. X   PROCEDURE InclChar(VAR charset: CharSet; ch: CHAR);
  359. X   BEGIN
  360. X      INCL(charset[ORD(ch) DIV setsize], ORD(ch) MOD setsize);
  361. X   END InclChar;
  362. X
  363. X   PROCEDURE ExclChar(VAR charset: CharSet; ch: CHAR);
  364. X   BEGIN
  365. X      EXCL(charset[ORD(ch) DIV setsize], ORD(ch) MOD setsize);
  366. X   END ExclChar;
  367. X
  368. X   PROCEDURE Intersection(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  369. X      VAR
  370. X     index: INTEGER;
  371. X   BEGIN
  372. X      IF (LEN(result) # LEN(set1)) OR (LEN(result) # LEN(set2)) THEN
  373. X     LengthError("Intersection"); InitSet(result); RETURN
  374. X      END;
  375. X      index := 0;
  376. X      WHILE index < LEN(result) DO
  377. X     result[index] := set1[index] * set2[index];
  378. X     INC(index);
  379. X      END;
  380. X   END Intersection;
  381. X
  382. X   PROCEDURE SymDifference(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  383. X      VAR
  384. X     index: INTEGER;
  385. X   BEGIN
  386. X      IF (LEN(result) # LEN(set1)) OR (LEN(result) # LEN(set2)) THEN
  387. X     LengthError("SymDifference"); InitSet(result); RETURN
  388. X      END;
  389. X      index := 0;
  390. X      WHILE index < LEN(result) DO
  391. X     result[index] := set1[index] / set2[index];
  392. X     INC(index);
  393. X      END;
  394. X   END SymDifference;
  395. X
  396. X   PROCEDURE Union(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  397. X      VAR
  398. X     index: INTEGER;
  399. X   BEGIN
  400. X      IF (LEN(result) # LEN(set1)) OR (LEN(result) # LEN(set2)) THEN
  401. X     LengthError("Union"); InitSet(result); RETURN
  402. X      END;
  403. X      index := 0;
  404. X      WHILE index < LEN(result) DO
  405. X     result[index] := set1[index] + set2[index];
  406. X     INC(index);
  407. X      END;
  408. X   END Union;
  409. X
  410. X   PROCEDURE Difference(set1, set2: ARRAY OF SET; VAR result: ARRAY OF SET);
  411. X      VAR
  412. X     index: INTEGER;
  413. X   BEGIN
  414. X      IF (LEN(result) # LEN(set1)) OR (LEN(result) # LEN(set2)) THEN
  415. X     LengthError("Difference"); InitSet(result); RETURN
  416. X      END;
  417. X      index := 0;
  418. X      WHILE index < LEN(result) DO
  419. X     result[index] := set1[index] - set2[index];
  420. X     INC(index);
  421. X      END;
  422. X   END Difference;
  423. X
  424. X   PROCEDURE Equal(set1, set2: ARRAY OF SET) : BOOLEAN;
  425. X      VAR
  426. X     index: INTEGER;
  427. X   BEGIN
  428. X      index := 0;
  429. X      WHILE (index < LEN(set1)) & (index < LEN(set2)) DO
  430. X     IF set1[index] # set2[index] THEN
  431. X        RETURN FALSE
  432. X     END;
  433. X     INC(index);
  434. X      END;
  435. X      WHILE index < LEN(set1) DO
  436. X     IF set1[index] # {} THEN
  437. X        RETURN FALSE
  438. X     END;
  439. X     INC(index);
  440. X      END;
  441. X      WHILE index < LEN(set2) DO
  442. X     IF set2[index] # {} THEN
  443. X        RETURN FALSE
  444. X     END;
  445. X     INC(index);
  446. X      END;
  447. X      RETURN TRUE
  448. X   END Equal;
  449. X
  450. X   PROCEDURE Subset(set1, set2: ARRAY OF SET) : BOOLEAN;
  451. X      VAR
  452. X     index: INTEGER;
  453. X   BEGIN
  454. X      index := 0;
  455. X      WHILE (index < LEN(set1)) & (index < LEN(set2)) DO
  456. X     IF set1[index] - set2[index] # {} THEN
  457. X        RETURN FALSE
  458. X     END;
  459. X     INC(index);
  460. X      END;
  461. X      WHILE index < LEN(set1) DO
  462. X     IF set1[index] # {} THEN
  463. X        RETURN FALSE
  464. X     END;
  465. X     INC(index);
  466. X      END;
  467. X      RETURN TRUE
  468. X   END Subset;
  469. X
  470. X   PROCEDURE Card(set: ARRAY OF SET) : INTEGER;
  471. X      VAR
  472. X     index: INTEGER;
  473. X     i: INTEGER;
  474. X     card: INTEGER;
  475. X   BEGIN
  476. X      card := 0;
  477. X      index := 0;
  478. X      WHILE index < LEN(set) DO
  479. X     i := 0;
  480. X     WHILE i <= MAX(SET) DO
  481. X        IF i IN set[index] THEN
  482. X           INC(card);
  483. X        END;
  484. X        INC(i);
  485. X     END;
  486. X     INC(index);
  487. X      END;
  488. X      RETURN card
  489. X   END Card;
  490. X
  491. BEGIN
  492. X   Assertions.Define(lengthError, "Sets");
  493. END Sets.
  494. SHAR_EOF
  495. chmod 0664 Sets.om ||
  496. echo 'restore of Sets.om failed'
  497. Wc_c="`wc -c < 'Sets.om'`"
  498. test 4661 -eq "$Wc_c" ||
  499.     echo 'Sets.om: original size 4661, current size' "$Wc_c"
  500. fi
  501. exit 0
  502. -- 
  503. _______________________________________________________________________________
  504.  
  505. Andreas Borchert, University of Ulm, SAI, D-W-7900 Ulm, Germany
  506. Internet: borchert@mathematik.uni-ulm.de
  507.