summaryrefslogtreecommitdiff
path: root/doc/ref/goops.texi
blob: 91902e492322beef9d73105d1f99ee91279ed024 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554
2555
2556
2557
2558
2559
2560
2561
2562
2563
2564
2565
2566
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580
2581
2582
2583
2584
2585
2586
2587
2588
2589
2590
2591
2592
2593
2594
2595
2596
2597
2598
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620
2621
2622
2623
2624
2625
2626
2627
2628
2629
2630
2631
2632
2633
2634
2635
2636
2637
2638
2639
2640
2641
2642
2643
2644
2645
2646
2647
2648
2649
2650
2651
2652
2653
2654
2655
2656
2657
2658
2659
2660
2661
2662
2663
2664
2665
2666
2667
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681
2682
2683
2684
2685
2686
2687
2688
2689
2690
2691
2692
2693
2694
2695
2696
2697
2698
2699
2700
2701
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721
2722
2723
2724
2725
2726
2727
2728
2729
2730
2731
2732
2733
2734
2735
2736
2737
2738
2739
2740
2741
2742
2743
2744
2745
2746
2747
2748
2749
2750
2751
2752
2753
2754
2755
2756
2757
2758
2759
2760
2761
2762
2763
2764
2765
2766
2767
2768
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783
2784
2785
2786
2787
2788
2789
2790
2791
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849
2850
2851
2852
2853
2854
2855
2856
2857
2858
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884
2885
2886
2887
2888
2889
2890
2891
2892
2893
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912
2913
2914
2915
2916
2917
2918
2919
2920
2921
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958
2959
2960
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
@c -*-texinfo-*-
@c This is part of the GNU Guile Reference Manual.
@c Copyright (C)  2008, 2009, 2011, 2017
@c   Free Software Foundation, Inc.
@c See the file guile.texi for copying conditions.

@macro goops
GOOPS
@end macro

@macro guile
Guile
@end macro

@node GOOPS
@chapter GOOPS

@goops{} is the object oriented extension to @guile{}. Its
implementation is derived from @w{STk-3.99.3} by Erick Gallesio and
version 1.3 of Gregor Kiczales' @cite{Tiny-Clos}.  It is very close in
spirit to CLOS, the Common Lisp Object System, but is adapted for the
Scheme language.

@goops{} is a full object oriented system, with classes, objects,
multiple inheritance, and generic functions with multi-method
dispatch.  Furthermore its implementation relies on a meta object
protocol --- which means that @goops{}'s core operations are themselves
defined as methods on relevant classes, and can be customised by
overriding or redefining those methods.

To start using @goops{} you first need to import the @code{(oop goops)}
module.  You can do this at the Guile REPL by evaluating:

@lisp
(use-modules (oop goops))
@end lisp
@findex (oop goops)

@menu
* Copyright Notice::
* Class Definition::
* Instance Creation::  
* Slot Options::
* Slot Description Example::
* Methods and Generic Functions::           
* Inheritance::                 
* Introspection::
* GOOPS Error Handling::
* GOOPS Object Miscellany::
* The Metaobject Protocol::
* Redefining a Class::
* Changing the Class of an Instance::
@end menu

@node Copyright Notice
@section Copyright Notice

The material in this chapter is partly derived from the STk Reference
Manual written by Erick Gallesio, whose copyright notice is as follows.

Copyright © 1993-1999 Erick Gallesio - I3S-CNRS/ESSI <eg@@unice.fr>
Permission to use, copy, modify, distribute,and license this
software and its documentation for any purpose is hereby granted,
provided that existing copyright notices are retained in all
copies and that this notice is included verbatim in any
distributions.  No written agreement, license, or royalty fee is
required for any of the authorized uses.
This software is provided ``AS IS'' without express or implied
warranty.

The material has been adapted for use in Guile, with the author's
permission.


@node Class Definition
@section Class Definition

A new class is defined with the @code{define-class} syntax:

@findex define-class
@cindex class
@lisp
(define-class @var{class} (@var{superclass} @dots{})
   @var{slot-description} @dots{}
   @var{class-option} @dots{})
@end lisp

@var{class} is the class being defined.  The list of @var{superclass}es
specifies which existing classes, if any, to inherit slots and
properties from.  @dfn{Slots} hold per-instance@footnote{Usually --- but
see also the @code{#:allocation} slot option.} data, for instances of
that class --- like ``fields'' or ``member variables'' in other object
oriented systems.  Each @var{slot-description} gives the name of a slot
and optionally some ``properties'' of this slot; for example its initial
value, the name of a function which will access its value, and so on.
Class options, slot descriptions and inheritance are discussed more
below.
@cindex slot

@deffn syntax define-class name (super @dots{}) @
              slot-definition @dots{} class-option @dots{}
Define a class called @var{name} that inherits from @var{super}s, with
direct slots defined by @var{slot-definition}s and @var{class-option}s.
The newly created class is bound to the variable name @var{name} in the
current environment.

Each @var{slot-definition} is either a symbol that names the slot or a
list,

@example
(@var{slot-name-symbol} . @var{slot-options})
@end example

where @var{slot-name-symbol} is a symbol and @var{slot-options} is a
list with an even number of elements.  The even-numbered elements of
@var{slot-options} (counting from zero) are slot option keywords; the
odd-numbered elements are the corresponding values for those keywords.

Each @var{class-option} is an option keyword and corresponding value.
@end deffn

As an example, let us define a type for representing a complex number
in terms of two real numbers.@footnote{Of course Guile already
provides complex numbers, and @code{<complex>} is in fact a predefined
class in GOOPS; but the definition here is still useful as an
example.}  This can be done with the following class definition:

@lisp
(define-class <my-complex> (<number>)
   r i)
@end lisp

This binds the variable @code{<my-complex>} to a new class whose
instances will contain two slots.  These slots are called @code{r} and
@code{i} and will hold the real and imaginary parts of a complex
number. Note that this class inherits from @code{<number>}, which is a
predefined class.@footnote{@code{<number>} is the direct superclass of
the predefined class @code{<complex>}; @code{<complex>} is the
superclass of @code{<real>}, and @code{<real>} is the superclass of
@code{<integer>}.}

Slot options are described in the next section.  The possible class
options are as follows.

@deffn {class option} #:metaclass metaclass
The @code{#:metaclass} class option specifies the metaclass of the class
being defined.  @var{metaclass} must be a class that inherits from
@code{<class>}.  For the use of metaclasses, see @ref{Metaobjects and
the Metaobject Protocol} and @ref{Metaclasses}.

If the @code{#:metaclass} option is absent, GOOPS reuses or constructs a
metaclass for the new class by calling @code{ensure-metaclass}
(@pxref{Class Definition Protocol,, ensure-metaclass}).
@end deffn

@deffn {class option} #:name name
The @code{#:name} class option specifies the new class's name.  This
name is used to identify the class whenever related objects - the class
itself, its instances and its subclasses - are printed.

If the @code{#:name} option is absent, GOOPS uses the first argument to
@code{define-class} as the class name.
@end deffn


@node Instance Creation
@section Instance Creation and Slot Access

An instance (or object) of a defined class can be created with
@code{make}.  @code{make} takes one mandatory parameter, which is the
class of the instance to create, and a list of optional arguments that
will be used to initialize the slots of the new instance.  For instance
the following form

@findex make
@cindex instance
@lisp
(define c (make <my-complex>))
@end lisp

@noindent
creates a new @code{<my-complex>} object and binds it to the Scheme
variable @code{c}.

@deffn generic make
@deffnx method make (class <class>) initarg @dots{}
Create and return a new instance of class @var{class}, initialized using
@var{initarg} @enddots{}.

In theory, @var{initarg} @dots{} can have any structure that is
understood by whatever methods get applied when the @code{initialize}
generic function is applied to the newly allocated instance.

In practice, specialized @code{initialize} methods would normally call
@code{(next-method)}, and so eventually the standard GOOPS
@code{initialize} methods are applied.  These methods expect
@var{initargs} to be a list with an even number of elements, where
even-numbered elements (counting from zero) are keywords and
odd-numbered elements are the corresponding values.

GOOPS processes initialization argument keywords automatically for slots
whose definition includes the @code{#:init-keyword} option (@pxref{Slot
Options,, init-keyword}).  Other keyword value pairs can only be
processed by an @code{initialize} method that is specialized for the new
instance's class.  Any unprocessed keyword value pairs are ignored.
@end deffn

@deffn generic make-instance
@deffnx method make-instance (class <class>) initarg @dots{}
@code{make-instance} is an alias for @code{make}.
@end deffn

The slots of the new complex number can be accessed using
@code{slot-ref} and @code{slot-set!}.  @code{slot-set!}  sets the value
of an object slot and @code{slot-ref} retrieves it.

@findex slot-set!
@findex slot-ref
@lisp
@group
(slot-set! c 'r 10)
(slot-set! c 'i 3)
(slot-ref c 'r) @result{} 10
(slot-ref c 'i) @result{} 3
@end group
@end lisp

The @code{(oop goops describe)} module provides a @code{describe}
function that is useful for seeing all the slots of an object; it prints
the slots and their values to standard output.

@lisp
(describe c)
@print{}
#<<my-complex> 401d8638> is an instance of class <my-complex>
Slots are: 
     r = 10
     i = 3
@end lisp


@node Slot Options
@section Slot Options

When specifying a slot (in a @code{(define-class @dots{})} form),
various options can be specified in addition to the slot's name.  Each
option is specified by a keyword.  The list of possible keywords is
as follows.

@deffn {slot option} #:init-value init-value
@deffnx {slot option} #:init-form init-form
@deffnx {slot option} #:init-thunk init-thunk
@deffnx {slot option} #:init-keyword init-keyword
These options provide various ways to specify how to initialize the
slot's value at instance creation time.
@cindex default slot value

@var{init-value} specifies a fixed initial slot value (shared across all
new instances of the class).

@var{init-thunk} specifies a thunk that will provide a default value for
the slot.  The thunk is called when a new instance is created and should
return the desired initial slot value.

@var{init-form} specifies a form that, when evaluated, will return
an initial value for the slot.  The form is evaluated each time that
an instance of the class is created, in the lexical environment of the
containing @code{define-class} expression.

@var{init-keyword} specifies a keyword that can be used to pass an
initial slot value to @code{make} when creating a new instance.

Note that, since an @code{init-value} value is shared across all
instances of a class, you should only use it when the initial value is
an immutable value, like a constant.  If you want to initialize a slot
with a fresh, independently mutable value, you should use
@code{init-thunk} or @code{init-form} instead.  Consider the following
example.

@example
(define-class <chbouib> ()
  (hashtab #:init-value (make-hash-table)))
@end example

@noindent
Here only one hash table is created and all instances of
@code{<chbouib>} have their @code{hashtab} slot refer to it.  In order
to have each instance of @code{<chbouib>} refer to a new hash table, you
should instead write:

@example
(define-class <chbouib> ()
  (hashtab #:init-thunk make-hash-table))
@end example

@noindent
or:

@example
(define-class <chbouib> ()
  (hashtab #:init-form (make-hash-table)))
@end example

If more than one of these options is specified for the same slot, the
order of precedence, highest first is

@itemize @bullet
@item
@code{#:init-keyword}, if @var{init-keyword} is present in the options
passed to @code{make}

@item
@code{#:init-thunk}, @code{#:init-form} or @code{#:init-value}.
@end itemize

If the slot definition contains more than one initialization option of
the same precedence, the later ones are ignored.  If a slot is not
initialized at all, its value is unbound.

In general, slots that are shared between more than one instance are
only initialized at new instance creation time if the slot value is
unbound at that time.  However, if the new instance creation specifies
a valid init keyword and value for a shared slot, the slot is
re-initialized regardless of its previous value.

Note, however, that the power of GOOPS' metaobject protocol means that
everything written here may be customized or overridden for particular
classes!  The slot initializations described here are performed by the least
specialized method of the generic function @code{initialize}, whose
signature is

@example
(define-method (initialize (object <object>) initargs) ...)
@end example

The initialization of instances of any given class can be customized by
defining a @code{initialize} method that is specialized for that class,
and the author of the specialized method may decide to call
@code{next-method} - which will result in a call to the next less
specialized @code{initialize} method - at any point within the
specialized code, or maybe not at all.  In general, therefore, the
initialization mechanisms described here may be modified or overridden by
more specialized code, or may not be supported at all for particular
classes.
@end deffn

@deffn {slot option} #:getter getter
@deffnx {slot option} #:setter setter
@deffnx {slot option} #:accessor accessor
Given an object @var{obj} with slots named @code{foo} and @code{bar}, it
is always possible to read and write those slots by calling
@code{slot-ref} and @code{slot-set!} with the relevant slot name; for
example:

@example
(slot-ref @var{obj} 'foo)
(slot-set! @var{obj} 'bar 25)
@end example

The @code{#:getter}, @code{#:setter} and @code{#:accessor} options, if
present, tell GOOPS to create generic function and method definitions
that can be used to get and set the slot value more conveniently.
@var{getter} specifies a generic function to which GOOPS will add a
method for getting the slot value.  @var{setter} specifies a generic
function to which GOOPS will add a method for setting the slot value.
@var{accessor} specifies an accessor to which GOOPS will add methods for
both getting and setting the slot value.

So if a class includes a slot definition like this:

@example
(c #:getter get-count #:setter set-count #:accessor count)
@end example

GOOPS defines generic function methods such that the slot value can be
referenced using either the getter or the accessor -

@example
(let ((current-count (get-count obj))) @dots{})
(let ((current-count (count obj))) @dots{})
@end example

- and set using either the setter or the accessor -

@example
(set-count obj (+ 1 current-count))
(set! (count obj) (+ 1 current-count))
@end example

Note that

@itemize @bullet
@item
with an accessor, the slot value is set using the generalized
@code{set!} syntax

@item
in practice, it is unusual for a slot to use all three of these options:
read-only, write-only and read-write slots would typically use only
@code{#:getter}, @code{#:setter} and @code{#:accessor} options
respectively.
@end itemize

The binding of the specified names is done in the environment of the
@code{define-class} expression.  If the names are already bound (in that
environment) to values that cannot be upgraded to generic functions,
those values are overwritten when the @code{define-class} expression is
evaluated.  For more detail, see @ref{Generic Function Internals,,
ensure-generic}.
@end deffn

@deffn {slot option} #:allocation allocation
The @code{#:allocation} option tells GOOPS how to allocate storage for
the slot.  Possible values for @var{allocation} are

@itemize @bullet
@item @code{#:instance}

@findex #:instance
Indicates that GOOPS should create separate storage for this slot in
each new instance of the containing class (and its subclasses).  This is
the default.

@item @code{#:class}

@findex #:class
Indicates that GOOPS should create storage for this slot that is shared
by all instances of the containing class (and its subclasses).  In other
words, a slot in class @var{C} with allocation @code{#:class} is shared
by all @var{instance}s for which @code{(is-a? @var{instance} @var{c})}.
This permits defining a kind of global variable which can be accessed
only by (in)direct instances of the class which defines the slot.

@item @code{#:each-subclass}

@findex #:each-subclass
Indicates that GOOPS should create storage for this slot that is shared
by all @emph{direct} instances of the containing class, and that
whenever a subclass of the containing class is defined, GOOPS should
create a new storage for the slot that is shared by all @emph{direct}
instances of the subclass.  In other words, a slot with allocation
@code{#:each-subclass} is shared by all instances with the same
@code{class-of}.

@item @code{#:virtual}

@findex #:slot-set!
@findex #:slot-ref
@findex #:virtual
Indicates that GOOPS should not allocate storage for this slot.  The
slot definition must also include the @code{#:slot-ref} and
@code{#:slot-set!} options to specify how to reference and set the value
for this slot.  See the example below.
@end itemize

Slot allocation options are processed when defining a new class by the
generic function @code{compute-get-n-set}, which is specialized by the
class's metaclass.  Hence new types of slot allocation can be
implemented by defining a new metaclass and a method for
@code{compute-get-n-set} that is specialized for the new metaclass.  For
an example of how to do this, see @ref{Customizing Class Definition}.
@end deffn

@deffn {slot option} #:slot-ref getter
@deffnx {slot option} #:slot-set! setter
The @code{#:slot-ref} and @code{#:slot-set!} options must be specified
if the slot allocation is @code{#:virtual}, and are ignored otherwise.

@var{getter} should be a closure taking a single @var{instance} parameter
that returns the current slot value.  @var{setter} should be a closure
taking two parameters - @var{instance} and @var{new-val} - that sets the
slot value to @var{new-val}.
@end deffn

@node Slot Description Example
@section Illustrating Slot Description

To illustrate slot description, we can redefine the @code{<my-complex>}
class seen before. A definition could be:

@lisp
(define-class <my-complex> (<number>) 
   (r #:init-value 0 #:getter get-r #:setter set-r! #:init-keyword #:r)
   (i #:init-value 0 #:getter get-i #:setter set-i! #:init-keyword #:i))
@end lisp

@noindent
With this definition, the @code{r} and @code{i} slots are set to 0 by
default, and can be initialised to other values by calling @code{make}
with the @code{#:r} and @code{#:i} keywords.  Also the generic functions
@code{get-r}, @code{set-r!}, @code{get-i} and @code{set-i!}  are
automatically defined to read and write the slots.

@lisp
(define c1 (make <my-complex> #:r 1 #:i 2))
(get-r c1) @result{} 1
(set-r! c1 12)
(get-r c1) @result{} 12
(define c2 (make <my-complex> #:r 2))
(get-r c2) @result{} 2
(get-i c2) @result{} 0
@end lisp

Accessors can both read and write a slot.  So, another definition of the
@code{<my-complex>} class, using the @code{#:accessor} option, could be:

@findex set!
@lisp
(define-class <my-complex> (<number>) 
   (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
   (i #:init-value 0 #:accessor imag-part #:init-keyword #:i))
@end lisp

@noindent
With this definition, the @code{r} slot can be read with:
@lisp
(real-part c)
@end lisp
@noindent
and set with:
@lisp
(set! (real-part c) new-value)
@end lisp

Suppose now that we want to manipulate complex numbers with both
rectangular and polar coordinates.  One solution could be to have a
definition of complex numbers which uses one particular representation
and some conversion functions to pass from one representation to the
other.  A better solution is to use virtual slots, like this:

@lisp
(define-class <my-complex> (<number>)
   ;; True slots use rectangular coordinates
   (r #:init-value 0 #:accessor real-part #:init-keyword #:r)
   (i #:init-value 0 #:accessor imag-part #:init-keyword #:i)
   ;; Virtual slots access do the conversion
   (m #:accessor magnitude #:init-keyword #:magn  
      #:allocation #:virtual
      #:slot-ref (lambda (o)
                  (let ((r (slot-ref o 'r)) (i (slot-ref o 'i)))
                    (sqrt (+ (* r r) (* i i)))))
      #:slot-set! (lambda (o m)
                    (let ((a (slot-ref o 'a)))
                      (slot-set! o 'r (* m (cos a)))
                      (slot-set! o 'i (* m (sin a))))))
   (a #:accessor angle #:init-keyword #:angle
      #:allocation #:virtual
      #:slot-ref (lambda (o)
                  (atan (slot-ref o 'i) (slot-ref o 'r)))
      #:slot-set! (lambda(o a)
                   (let ((m (slot-ref o 'm)))
                      (slot-set! o 'r (* m (cos a)))
                      (slot-set! o 'i (* m (sin a)))))))

@end lisp

In this class definition, the magnitude @code{m} and angle @code{a}
slots are virtual, and are calculated, when referenced, from the normal
(i.e.@: @code{#:allocation #:instance}) slots @code{r} and @code{i}, by
calling the function defined in the relevant @code{#:slot-ref} option.
Correspondingly, writing @code{m} or @code{a} leads to calling the
function defined in the @code{#:slot-set!} option.  Thus the
following expression

@findex #:slot-set!
@findex #:slot-ref
@lisp
(slot-set! c 'a 3)
@end lisp

@noindent
permits to set the angle of the @code{c} complex number.

@lisp
(define c (make <my-complex> #:r 12 #:i 20))
(real-part c) @result{} 12
(angle c) @result{} 1.03037682652431
(slot-set! c 'i 10)
(set! (real-part c) 1)
(describe c)
@print{}
#<<my-complex> 401e9b58> is an instance of class <my-complex>
Slots are: 
     r = 1
     i = 10
     m = 10.0498756211209
     a = 1.47112767430373
@end lisp

Since initialization keywords have been defined for the four slots, we
can now define the standard Scheme primitives @code{make-rectangular}
and @code{make-polar}.

@lisp
(define make-rectangular 
   (lambda (x y) (make <my-complex> #:r x #:i y)))

(define make-polar
   (lambda (x y) (make <my-complex> #:magn x #:angle y)))
@end lisp


@node Methods and Generic Functions
@section Methods and Generic Functions

A GOOPS method is like a Scheme procedure except that it is specialized
for a particular set of argument classes, and will only be used when the
actual arguments in a call match the classes in the method definition.

@lisp
(define-method (+ (x <string>) (y <string>))
  (string-append x y))

(+ "abc" "de") @result{} "abcde"
@end lisp

A method is not formally associated with any single class (as it is in
many other object oriented languages), because a method can be
specialized for a combination of several classes.  If you've studied
object orientation in non-Lispy languages, you may remember discussions
such as whether a method to stretch a graphical image around a surface
should be a method of the image class, with a surface as a parameter, or
a method of the surface class, with an image as a parameter.  In GOOPS
you'd just write

@lisp
(define-method (stretch (im <image>) (sf <surface>))
  ...)
@end lisp

@noindent
and the question of which class the method is more associated with does
not need answering.

There can simultaneously be several methods with the same name but
different sets of specializing argument classes; for example:

@lisp
(define-method (+ (x <string>) (y <string)) ...)
(define-method (+ (x <matrix>) (y <matrix>)) ...)
(define-method (+ (f <fish>) (b <bicycle>)) ...)
(define-method (+ (a <foo>) (b <bar>) (c <baz>)) ...)
@end lisp

@noindent
A generic function is a container for the set of such methods that a
program intends to use.

If you look at a program's source code, and see @code{(+ x y)} somewhere
in it, conceptually what is happening is that the program at that point
calls a generic function (in this case, the generic function bound to
the identifier @code{+}).  When that happens, Guile works out which of
the generic function's methods is the most appropriate for the arguments
that the function is being called with; then it evaluates the method's
code with the arguments as formal parameters.  This happens every time
that a generic function call is evaluated --- it isn't assumed that a
given source code call will end up invoking the same method every time.

Defining an identifier as a generic function is done with the
@code{define-generic} macro.  Definition of a new method is done with
the @code{define-method} macro.  Note that @code{define-method}
automatically does a @code{define-generic} if the identifier concerned
is not already a generic function, so often an explicit
@code{define-generic} call is not needed.
@findex define-generic
@findex define-method

@deffn syntax define-generic symbol
Create a generic function with name @var{symbol} and bind it to the
variable @var{symbol}.  If @var{symbol} was previously bound to a Scheme
procedure (or procedure-with-setter), the old procedure (and setter) is
incorporated into the new generic function as its default procedure (and
setter).  Any other previous value, including an existing generic
function, is discarded and replaced by a new, empty generic function.
@end deffn

@deffn syntax define-method (generic parameter @dots{}) body @dots{}
Define a method for the generic function or accessor @var{generic} with
parameters @var{parameter}s and body @var{body} @enddots{}.

@var{generic} is a generic function.  If @var{generic} is a variable
which is not yet bound to a generic function object, the expansion of
@code{define-method} will include a call to @code{define-generic}.  If
@var{generic} is @code{(setter @var{generic-with-setter})}, where
@var{generic-with-setter} is a variable which is not yet bound to a
generic-with-setter object, the expansion will include a call to
@code{define-accessor}.

Each @var{parameter} must be either a symbol or a two-element list
@code{(@var{symbol} @var{class})}.  The symbols refer to variables in
the body forms that will be bound to the parameters supplied by the
caller when calling this method.  The @var{class}es, if present,
specify the possible combinations of parameters to which this method
can be applied.

@var{body} @dots{} are the bodies of the method definition.
@end deffn

@code{define-method} expressions look a little like Scheme procedure
definitions of the form

@example
(define (name formals @dots{}) . body)
@end example

The important difference is that each formal parameter, apart from the
possible ``rest'' argument, can be qualified by a class name:
@code{@var{formal}} becomes @code{(@var{formal} @var{class})}.  The
meaning of this qualification is that the method being defined
will only be applicable in a particular generic function invocation if
the corresponding argument is an instance of @code{@var{class}} (or one of
its subclasses).  If more than one of the formal parameters is qualified
in this way, then the method will only be applicable if each of the
corresponding arguments is an instance of its respective qualifying class.

Note that unqualified formal parameters act as though they are qualified
by the class @code{<top>}, which GOOPS uses to mean the superclass of
all valid Scheme types, including both primitive types and GOOPS classes.

For example, if a generic function method is defined with
@var{parameter}s @code{(s1 <square>)} and @code{(n <number>)}, that
method is only applicable to invocations of its generic function that
have two parameters where the first parameter is an instance of the
@code{<square>} class and the second parameter is a number.

@menu
* Accessors::
* Extending Primitives::
* Merging Generics::
* Next-method::                 
* Generic Function and Method Examples::                     
* Handling Invocation Errors::
@end menu


@node Accessors
@subsection Accessors

An accessor is a generic function that can also be used with the
generalized @code{set!} syntax (@pxref{Procedures with Setters}).  Guile
will handle a call like

@example
(set! (@code{accessor} @code{args}@dots{}) @code{value})
@end example

@noindent
by calling the most specialized method of @code{accessor} that matches
the classes of @code{args} and @code{value}.  @code{define-accessor} is
used to bind an identifier to an accessor.

@deffn syntax define-accessor symbol
Create an accessor with name @var{symbol} and bind it to the variable
@var{symbol}.  If @var{symbol} was previously bound to a Scheme
procedure (or procedure-with-setter), the old procedure (and setter) is
incorporated into the new accessor as its default procedure (and
setter).  Any other previous value, including an existing generic
function or accessor, is discarded and replaced by a new, empty
accessor.
@end deffn


@node Extending Primitives
@subsection Extending Primitives

Many of Guile's primitive procedures can be extended by giving them a
generic function definition that operates in conjunction with their
normal C-coded implementation.  When a primitive is extended in this
way, it behaves like a generic function with the C-coded implementation
as its default method.

This extension happens automatically if a method is defined (by a
@code{define-method} call) for a variable whose current value is a
primitive.  But it can also be forced by calling
@code{enable-primitive-generic!}.

@deffn {primitive procedure} enable-primitive-generic! primitive
Force the creation of a generic function definition for
@var{primitive}.
@end deffn

Once the generic function definition for a primitive has been created,
it can be retrieved using @code{primitive-generic-generic}.

@deffn {primitive procedure} primitive-generic-generic primitive
Return the generic function definition of @var{primitive}.

@code{primitive-generic-generic} raises an error if @var{primitive}
is not a primitive with generic capability.
@end deffn

@node Merging Generics
@subsection Merging Generics

GOOPS generic functions and accessors often have short, generic names.
For example, if a vector package provides an accessor for the X
coordinate of a vector, that accessor may just be called @code{x}.  It
doesn't need to be called, for example, @code{vector:x}, because
GOOPS will work out, when it sees code like @code{(x @var{obj})}, that
the vector-specific method of @code{x} should be called if @var{obj} is
a vector.

That raises the question, though, of what happens when different
packages define a generic function with the same name.  Suppose we work
with a graphical package which needs to use two independent vector
packages for 2D and 3D vectors respectively.  If both packages export
@code{x}, what does the code using those packages end up with?

@ref{Creating Guile Modules,,duplicate binding handlers} explains how
this is resolved for conflicting bindings in general.  For generics,
there is a special duplicates handler, @code{merge-generics}, which
tells the module system to merge generic functions with the same name.
Here is an example:

@lisp
(define-module (math 2D-vectors)
  #:use-module (oop goops)
  #:export (x y ...))
		  
(define-module (math 3D-vectors)
  #:use-module (oop goops)
  #:export (x y z ...))

(define-module (my-module)
  #:use-module (oop goops)
  #:use-module (math 2D-vectors)
  #:use-module (math 3D-vectors)
  #:duplicates (merge-generics))
@end lisp

The generic function @code{x} in @code{(my-module)} will now incorporate
all of the methods of @code{x} from both imported modules.

To be precise, there will now be three distinct generic functions named
@code{x}: @code{x} in @code{(math 2D-vectors)}, @code{x} in @code{(math
3D-vectors)}, and @code{x} in @code{(my-module)}; and these functions
share their methods in an interesting and dynamic way.

To explain, let's call the imported generic functions (in @code{(math
2D-vectors)} and @code{(math 3D-vectors)}) the @dfn{ancestors}, and the
merged generic function (in @code{(my-module)}), the @dfn{descendant}.
The general rule is that for any generic function G, the applicable
methods are selected from the union of the methods of G's descendant
functions, the methods of G itself and the methods of G's ancestor
functions.

Thus ancestor functions effectively share methods with their
descendants, and vice versa.  In the example above, @code{x} in
@code{(math 2D-vectors)} will share the methods of @code{x} in
@code{(my-module)} and vice versa.@footnote{But note that @code{x} in
@code{(math 2D-vectors)} doesn't share methods with @code{x} in
@code{(math 3D-vectors)}, so modularity is still preserved.}  Sharing is
dynamic, so adding another new method to a descendant implies adding it
to that descendant's ancestors too.

@node Next-method
@subsection Next-method

When you call a generic function, with a particular set of arguments,
GOOPS builds a list of all the methods that are applicable to those
arguments and orders them by how closely the method definitions match
the actual argument types.  It then calls the method at the top of this
list.  If the selected method's code wants to call on to the next method
in this list, it can do so by using @code{next-method}.

@lisp
(define-method (Test (a <integer>)) (cons 'integer (next-method)))
(define-method (Test (a <number>))  (cons 'number  (next-method)))
(define-method (Test a)             (list 'top))
@end lisp

With these definitions,

@lisp
(Test 1)   @result{} (integer number top)
(Test 1.0) @result{} (number top)
(Test #t)  @result{} (top)
@end lisp

@code{next-method} is always called as just @code{(next-method)}.  The
arguments for the next method call are always implicit, and always the
same as for the original method call.

If you want to call on to a method with the same name but with a
different set of arguments (as you might with overloaded methods in C++,
for example), you do not use @code{next-method}, but instead simply
write the new call as usual:

@lisp
(define-method (Test (a <number>) min max)
  (if (and (>= a min) (<= a max))
      (display "Number is in range\n"))
  (Test a))

(Test 2 1 10)
@print{}
Number is in range
@result{}
(integer number top)
@end lisp

(You should be careful in this case that the @code{Test} calls do not
lead to an infinite recursion, but this consideration is just the same
as in Scheme code in general.)

@node Generic Function and Method Examples
@subsection Generic Function and Method Examples

Consider the following definitions:

@lisp
(define-generic G)
(define-method (G (a <integer>) b) 'integer)
(define-method (G (a <real>) b) 'real)
(define-method (G a b) 'top)
@end lisp

The @code{define-generic} call defines @var{G} as a generic function.
The three next lines define methods for @var{G}.  Each method uses a
sequence of @dfn{parameter specializers} that specify when the given
method is applicable.  A specializer permits to indicate the class a
parameter must belong to (directly or indirectly) to be applicable.  If
no specializer is given, the system defaults it to @code{<top>}.  Thus,
the first method definition is equivalent to

@cindex parameter specializers
@lisp
(define-method (G (a <integer>) (b <top>)) 'integer)
@end lisp

Now, let's look at some possible calls to the generic function @var{G}:

@lisp
(G 2 3)    @result{} integer
(G 2 #t)   @result{} integer
(G 1.2 'a) @result{} real
@c (G #3 'a) @result{} real       @c was {\sharpsign}
(G #t #f)  @result{} top
(G 1 2 3)  @result{} error (since no method exists for 3 parameters)
@end lisp

The methods above use only one specializer per parameter list.  But in
general, any or all of a method's parameters may be specialized.
Suppose we define now:

@lisp
(define-method (G (a <integer>) (b <number>))  'integer-number)
(define-method (G (a <integer>) (b <real>))    'integer-real)
(define-method (G (a <integer>) (b <integer>)) 'integer-integer)
(define-method (G a (b <number>))              'top-number)
@end lisp

@noindent With these definitions:

@lisp
(G 1 2)   @result{} integer-integer
(G 1 1.0) @result{} integer-real
(G 1 #t)  @result{} integer
(G 'a 1)  @result{} top-number
@end lisp

As a further example we shall continue to define operations on the
@code{<my-complex>} class.  Suppose that we want to use it to implement
complex numbers completely.  For instance a definition for the addition
of two complex numbers could be

@lisp
(define-method (new-+ (a <my-complex>) (b <my-complex>))
  (make-rectangular (+ (real-part a) (real-part b))
                    (+ (imag-part a) (imag-part b))))
@end lisp

To be sure that the @code{+} used in the method @code{new-+} is the
standard addition we can do:

@lisp
(define-generic new-+)

(let ((+ +))
  (define-method (new-+ (a <my-complex>) (b <my-complex>))
    (make-rectangular (+ (real-part a) (real-part b))
                      (+ (imag-part a) (imag-part b)))))
@end lisp

The @code{define-generic} ensures here that @code{new-+} will be defined
in the global environment. Once this is done, we can add methods to the
generic function @code{new-+} which make a closure on the @code{+}
symbol.  A complete writing of the @code{new-+} methods is shown in
@ref{fig:newplus}.

@float Figure,fig:newplus
@lisp
(define-generic new-+)

(let ((+ +))

  (define-method (new-+ (a <real>) (b <real>)) (+ a b))

  (define-method (new-+ (a <real>) (b <my-complex>)) 
    (make-rectangular (+ a (real-part b)) (imag-part b)))

  (define-method (new-+ (a <my-complex>) (b <real>))
    (make-rectangular (+ (real-part a) b) (imag-part a)))

  (define-method (new-+ (a <my-complex>) (b <my-complex>))
    (make-rectangular (+ (real-part a) (real-part b))
                      (+ (imag-part a) (imag-part b))))

  (define-method (new-+ (a <number>))  a)
  
  (define-method (new-+) 0)

  (define-method (new-+ . args)
    (new-+ (car args) 
      (apply new-+ (cdr args)))))

(set! + new-+)
@end lisp

@caption{Extending @code{+} to handle complex numbers}
@end float

We take advantage here of the fact that generic function are not obliged
to have a fixed number of parameters.  The four first methods implement
dyadic addition.  The fifth method says that the addition of a single
element is this element itself.  The sixth method says that using the
addition with no parameter always return 0 (as is also true for the
primitive @code{+}).  The last method takes an arbitrary number of
parameters@footnote{The parameter list for a @code{define-method}
follows the conventions used for Scheme procedures. In particular it can
use the dot notation or a symbol to denote an arbitrary number of
parameters}.  This method acts as a kind of @code{reduce}: it calls the
dyadic addition on the @emph{car} of the list and on the result of
applying it on its rest.  To finish, the @code{set!} permits to redefine
the @code{+} symbol to our extended addition.

To conclude our implementation (integration?) of complex numbers, we
could redefine standard Scheme predicates in the following manner:

@lisp
(define-method (complex? c <my-complex>) #t)
(define-method (complex? c)           #f)

(define-method (number? n <number>) #t)
(define-method (number? n)          #f)
@dots{}
@end lisp

Standard primitives in which complex numbers are involved could also be
redefined in the same manner.


@node Handling Invocation Errors
@subsection Handling Invocation Errors

If a generic function is invoked with a combination of parameters for
which there is no applicable method, GOOPS raises an error.

@deffn generic no-method
@deffnx method no-method (gf <generic>) args
When an application invokes a generic function, and no methods at all
have been defined for that generic function, GOOPS calls the
@code{no-method} generic function.  The default method calls
@code{goops-error} with an appropriate message.
@end deffn

@deffn generic no-applicable-method
@deffnx method no-applicable-method (gf <generic>) args
When an application applies a generic function to a set of arguments,
and no methods have been defined for those argument types, GOOPS calls
the @code{no-applicable-method} generic function.  The default method
calls @code{goops-error} with an appropriate message.
@end deffn

@deffn generic no-next-method
@deffnx method no-next-method (gf <generic>) args
When a generic function method calls @code{(next-method)} to invoke the
next less specialized method for that generic function, and no less
specialized methods have been defined for the current generic function
arguments, GOOPS calls the @code{no-next-method} generic function.  The
default method calls @code{goops-error} with an appropriate message.
@end deffn


@node Inheritance
@section Inheritance

Here are some class definitions to help illustrate inheritance:

@lisp
(define-class A () a)
(define-class B () b)
(define-class C () c)
(define-class D (A B) d a)
(define-class E (A C) e c)
(define-class F (D E) f)
@end lisp

@code{A}, @code{B}, @code{C} have a null list of superclasses.  In this
case, the system will replace the null list by a list which only
contains @code{<object>}, the root of all the classes defined by
@code{define-class}.  @code{D}, @code{E}, @code{F} use multiple
inheritance: each class inherits from two previously defined classes.
Those class definitions define a hierarchy which is shown in
@ref{fig:hier}.  In this figure, the class @code{<top>} is also shown;
this class is the superclass of all Scheme objects.  In particular,
@code{<top>} is the superclass of all standard Scheme
types.

@float Figure,fig:hier
@iftex
@center @image{hierarchy,5in}
@end iftex
@ifnottex
@verbatiminclude hierarchy.txt
@end ifnottex

@caption{A class hierarchy.}
@end float

When a class has superclasses, its set of slots is calculated by taking
the union of its own slots and those of all its superclasses.  Thus each
instance of D will have three slots, @code{a}, @code{b} and
@code{d}). The slots of a class can be discovered using the
@code{class-slots} primitive.  For instance,

@lisp
(class-slots A) @result{} ((a))
(class-slots E) @result{} ((a) (e) (c))
(class-slots F) @result{} ((e) (c) (b) (d) (a) (f))
@end lisp

@noindent
The ordering of the returned slots is not significant.

@menu
* Class Precedence List::
* Sorting Methods::
@end menu


@node Class Precedence List
@subsection Class Precedence List

What happens when a class inherits from two or more superclasses that
have a slot with the same name but incompatible definitions --- for
example, different init values or slot allocations?  We need a rule for
deciding which slot definition the derived class ends up with, and this
rule is provided by the class's @dfn{Class Precedence
List}.@footnote{This section is an adaptation of material from Jeff
Dalton's (J.Dalton@@ed.ac.uk) @cite{Brief introduction to CLOS}}

Another problem arises when invoking a generic function, and there is
more than one method that could apply to the call arguments.  Here we
need a way of ordering the applicable methods, so that Guile knows which
method to use first, which to use next if that method calls
@code{next-method}, and so on.  One of the ingredients for this ordering
is determining, for each given call argument, which of the specializing
classes, from each applicable method's definition, is the most specific
for that argument; and here again the class precedence list helps.

If inheritance was restricted such that each class could only have one
superclass --- which is known as @dfn{single} inheritance --- class
ordering would be easy.  The rule would be simply that a subclass is
considered more specific than its superclass.

With multiple inheritance, ordering is less obvious, and we have to
impose an arbitrary rule to determine precedence. Suppose we have

@lisp
(define-class X ()
   (x #:init-value 1))

(define-class Y ()
   (x #:init-value 2))

(define-class Z (X Y)
   (@dots{}))
@end lisp

@noindent
Clearly the @code{Z} class is more specific than @code{X} or @code{Y},
for instances of @code{Z}.  But which is more specific out of @code{X}
and @code{Y} --- and hence, for the definitions above, which
@code{#:init-value} will take effect when creating an instance of
@code{Z}?  The rule in @goops{} is that the superclasses listed earlier
are more specific than those listed later.  Hence @code{X} is more
specific than @code{Y}, and the @code{#:init-value} for slot @code{x} in
instances of @code{Z} will be 1.

Hence there is a linear ordering for a class and all its
superclasses, from most specific to least specific, and this ordering is
called the Class Precedence List of the class.

In fact the rules above are not quite enough to always determine a
unique order, but they give an idea of how things work.  For example,
for the @code{F} class shown in @ref{fig:hier}, the class precedence
list is

@example
(f d e a c b <object> <top>)
@end example

@noindent
In cases where there is any ambiguity (like this one), it is a bad idea
for programmers to rely on exactly what the order is.  If the order for
some superclasses is important, it can be expressed directly in the
class definition.

The precedence list of a class can be obtained by calling
@code{class-precedence-list}.  This function returns a ordered list
whose first element is the most specific class.  For instance:

@lisp
(class-precedence-list B) @result{} (#<<class> B 401b97c8> 
                                     #<<class> <object> 401e4a10> 
                                     #<<class> <top> 4026a9d8>)
@end lisp

@noindent
Or for a more immediately readable result:

@lisp
(map class-name (class-precedence-list B)) @result{} (B <object> <top>) 
@end lisp


@node Sorting Methods
@subsection Sorting Methods

Now, with the idea of the class precedence list, we can state precisely
how the possible methods are sorted when more than one of the methods of
a generic function are applicable to the call arguments.

The rules are that
@itemize
@item
the applicable methods are sorted in order of specificity, and the most
specific method is used first, then the next if that method calls
@code{next-method}, and so on

@item
a method M1 is more specific than another method M2 if the first
specializing class that differs, between the definitions of M1 and M2,
is more specific, in M1's definition, for the corresponding actual call
argument, than the specializing class in M2's definition

@item
a class C1 is more specific than another class C2, for an object of
actual class C, if C1 comes before C2 in C's class precedence list.
@end itemize


@node Introspection
@section Introspection

@dfn{Introspection}, or @dfn{reflection}, means being able to obtain
information dynamically about GOOPS objects.  It is perhaps best
illustrated by considering an object oriented language that does not
provide any introspection, namely C++.

Nothing in C++ allows a running program to obtain answers to the following
types of question:

@itemize @bullet
@item
What are the data members of this object or class?

@item
What classes does this class inherit from?

@item
Is this method call virtual or non-virtual?

@item
If I invoke @code{Employee::adjustHoliday()}, what class contains the
@code{adjustHoliday()} method that will be applied?
@end itemize

In C++, answers to such questions can only be determined by looking at
the source code, if you have access to it.  GOOPS, on the other hand,
includes procedures that allow answers to these questions --- or their
GOOPS equivalents --- to be obtained dynamically, at run time.

@menu
* Classes::
* Instances::
* Slots::
* Generic Functions::
* Accessing Slots::
@end menu

@node Classes
@subsection Classes

A GOOPS class is itself an instance of the @code{<class>} class, or of a
subclass of @code{<class>}.  The definition of the @code{<class>} class
has slots that are used to describe the properties of a class, including
the following.

@deffn {primitive procedure} class-name class
Return the name of class @var{class}.  This is the value of
@var{class}'s @code{name} slot.
@end deffn

@deffn {primitive procedure} class-direct-supers class
Return a list containing the direct superclasses of @var{class}.  This
is the value of @var{class}'s @code{direct-supers} slot.
@end deffn

@deffn {primitive procedure} class-direct-slots class
Return a list containing the slot definitions of the direct slots of
@var{class}.  This is the value of @var{class}'s @code{direct-slots}
slot.
@end deffn

@deffn {primitive procedure} class-direct-subclasses class
Return a list containing the direct subclasses of @var{class}.  This is
the value of @var{class}'s @code{direct-subclasses} slot.
@end deffn

@deffn {primitive procedure} class-direct-methods class
Return a list of all the generic function methods that use @var{class}
as a formal parameter specializer.  This is the value of @var{class}'s
@code{direct-methods} slot.
@end deffn

@deffn {primitive procedure} class-precedence-list class
Return the class precedence list for class @var{class} (@pxref{Class
Precedence List}).  This is the value of @var{class}'s @code{cpl} slot.
@end deffn

@deffn {primitive procedure} class-slots class
Return a list containing the slot definitions for all @var{class}'s
slots, including any slots that are inherited from superclasses.  This
is the value of @var{class}'s @code{slots} slot.
@end deffn

@deffn procedure class-subclasses class
Return a list of all subclasses of @var{class}.
@end deffn

@deffn procedure class-methods class
Return a list of all methods that use @var{class} or a subclass of
@var{class} as one of its formal parameter specializers.
@end deffn


@node Instances
@subsection Instances

@deffn {primitive procedure} class-of value
Return the GOOPS class of any Scheme @var{value}.
@end deffn

@deffn {primitive procedure} instance? object
Return @code{#t} if @var{object} is any GOOPS instance, otherwise
@code{#f}.
@end deffn

@deffn procedure is-a? object class
Return @code{#t} if @var{object} is an instance of @var{class} or one of
its subclasses.
@end deffn

You can use the @code{is-a?} predicate to ask whether any given value
belongs to a given class, or @code{class-of} to discover the class of a
given value.  Note that when GOOPS is loaded (by code using the
@code{(oop goops)} module) built-in classes like @code{<string>},
@code{<list>} and @code{<number>} are automatically set up,
corresponding to all Guile Scheme types.

@lisp
(is-a? 2.3 <number>) @result{} #t
(is-a? 2.3 <real>) @result{} #t
(is-a? 2.3 <string>) @result{} #f
(is-a? '("a" "b") <string>) @result{} #f
(is-a? '("a" "b") <list>) @result{} #t
(is-a? (car '("a" "b")) <string>) @result{} #t
(is-a? <string> <class>) @result{} #t
(is-a? <class> <string>) @result{} #f

(class-of 2.3) @result{} #<<class> <real> 908c708>
(class-of #(1 2 3)) @result{} #<<class> <vector> 908cd20>
(class-of <string>) @result{} #<<class> <class> 8bd3e10>
(class-of <class>) @result{} #<<class> <class> 8bd3e10>
@end lisp


@node Slots
@subsection Slots

@deffn procedure class-slot-definition class slot-name
Return the slot definition for the slot named @var{slot-name} in class
@var{class}.  @var{slot-name} should be a symbol.
@end deffn

@deffn procedure slot-definition-name slot-def
Extract and return the slot name from @var{slot-def}.
@end deffn

@deffn procedure slot-definition-options slot-def
Extract and return the slot options from @var{slot-def}.
@end deffn

@deffn procedure slot-definition-allocation slot-def
Extract and return the slot allocation option from @var{slot-def}.  This
is the value of the @code{#:allocation} keyword (@pxref{Slot Options,,
allocation}), or @code{#:instance} if the @code{#:allocation} keyword is
absent.
@end deffn

@deffn procedure slot-definition-getter slot-def
Extract and return the slot getter option from @var{slot-def}.  This is
the value of the @code{#:getter} keyword (@pxref{Slot Options,,
getter}), or @code{#f} if the @code{#:getter} keyword is absent.
@end deffn

@deffn procedure slot-definition-setter slot-def
Extract and return the slot setter option from @var{slot-def}.  This is
the value of the @code{#:setter} keyword (@pxref{Slot Options,,
setter}), or @code{#f} if the @code{#:setter} keyword is absent.
@end deffn

@deffn procedure slot-definition-accessor slot-def
Extract and return the slot accessor option from @var{slot-def}.  This
is the value of the @code{#:accessor} keyword (@pxref{Slot Options,,
accessor}), or @code{#f} if the @code{#:accessor} keyword is absent.
@end deffn

@deffn procedure slot-definition-init-value slot-def
Extract and return the slot init-value option from @var{slot-def}.  This
is the value of the @code{#:init-value} keyword (@pxref{Slot Options,,
init-value}), or the unbound value if the @code{#:init-value} keyword is
absent.
@end deffn

@deffn procedure slot-definition-init-form slot-def
Extract and return the slot init-form option from @var{slot-def}.  This
is the value of the @code{#:init-form} keyword (@pxref{Slot Options,,
init-form}), or the unbound value if the @code{#:init-form} keyword is
absent.
@end deffn

@deffn procedure slot-definition-init-thunk slot-def
Extract and return the slot init-thunk option from @var{slot-def}.  This
is the value of the @code{#:init-thunk} keyword (@pxref{Slot Options,,
init-thunk}), or @code{#f} if the @code{#:init-thunk} keyword is absent.
@end deffn

@deffn procedure slot-definition-init-keyword slot-def
Extract and return the slot init-keyword option from @var{slot-def}.
This is the value of the @code{#:init-keyword} keyword (@pxref{Slot
Options,, init-keyword}), or @code{#f} if the @code{#:init-keyword}
keyword is absent.
@end deffn

@deffn procedure slot-init-function class slot-name
Return the initialization function for the slot named @var{slot-name} in
class @var{class}.  @var{slot-name} should be a symbol.

The returned initialization function incorporates the effects of the
standard @code{#:init-thunk}, @code{#:init-form} and @code{#:init-value}
slot options.  These initializations can be overridden by the
@code{#:init-keyword} slot option or by a specialized @code{initialize}
method, so, in general, the function returned by
@code{slot-init-function} may be irrelevant.  For a fuller discussion,
see @ref{Slot Options,, init-value}.
@end deffn


@node Generic Functions
@subsection Generic Functions

A generic function is an instance of the @code{<generic>} class, or of a
subclass of @code{<generic>}.  The definition of the @code{<generic>}
class has slots that are used to describe the properties of a generic
function.

@deffn {primitive procedure} generic-function-name gf
Return the name of generic function @var{gf}.
@end deffn

@deffn {primitive procedure} generic-function-methods gf
Return a list of the methods of generic function @var{gf}.  This is the
value of @var{gf}'s @code{methods} slot.
@end deffn

Similarly, a method is an instance of the @code{<method>} class, or of a
subclass of @code{<method>}; and the definition of the @code{<method>}
class has slots that are used to describe the properties of a method.

@deffn {primitive procedure} method-generic-function method
Return the generic function that @var{method} belongs to.  This is the
value of @var{method}'s @code{generic-function} slot.
@end deffn

@deffn {primitive procedure} method-specializers method
Return a list of @var{method}'s formal parameter specializers .  This is
the value of @var{method}'s @code{specializers} slot.
@end deffn

@deffn {primitive procedure} method-procedure method
Return the procedure that implements @var{method}.  This is the value of
@var{method}'s @code{procedure} slot.
@end deffn

@deffn generic method-source
@deffnx method method-source (m <method>)
Return an expression that prints to show the definition of method
@var{m}.

@example
(define-generic cube)

(define-method (cube (n <number>))
  (* n n n))

(map method-source (generic-function-methods cube))
@result{}
((method ((n <number>)) (* n n n)))
@end example
@end deffn


@node Accessing Slots
@subsection Accessing Slots

Any slot, regardless of its allocation, can be queried, referenced and
set using the following four primitive procedures.

@deffn {primitive procedure} slot-exists? obj slot-name
Return @code{#t} if @var{obj} has a slot with name @var{slot-name},
otherwise @code{#f}.
@end deffn

@deffn {primitive procedure} slot-bound? obj slot-name
Return @code{#t} if the slot named @var{slot-name} in @var{obj} has a
value, otherwise @code{#f}.

@code{slot-bound?} calls the generic function @code{slot-missing} if
@var{obj} does not have a slot called @var{slot-name} (@pxref{Accessing
Slots, slot-missing}).
@end deffn

@deffn {primitive procedure} slot-ref obj slot-name
Return the value of the slot named @var{slot-name} in @var{obj}.

@code{slot-ref} calls the generic function @code{slot-missing} if
@var{obj} does not have a slot called @var{slot-name} (@pxref{Accessing
Slots, slot-missing}).

@code{slot-ref} calls the generic function @code{slot-unbound} if the
named slot in @var{obj} does not have a value (@pxref{Accessing Slots,
slot-unbound}).
@end deffn

@deffn {primitive procedure} slot-set! obj slot-name value
Set the value of the slot named @var{slot-name} in @var{obj} to @var{value}.

@code{slot-set!} calls the generic function @code{slot-missing} if
@var{obj} does not have a slot called @var{slot-name} (@pxref{Accessing
Slots, slot-missing}).
@end deffn

GOOPS stores information about slots in classes.  Internally,
all of these procedures work by looking up the slot definition for the
slot named @var{slot-name} in the class @code{(class-of
@var{obj})}, and then using the slot definition's ``getter'' and
``setter'' closures to get and set the slot value.

The next four procedures differ from the previous ones in that they take
the class as an explicit argument, rather than assuming
@code{(class-of @var{obj})}.  Therefore they allow you to apply the
``getter'' and ``setter'' closures of a slot definition in one class to
an instance of a different class.

@deffn {primitive procedure} slot-exists-using-class? class obj slot-name
Return @code{#t} if @var{class} has a slot definition for a slot with
name @var{slot-name}, otherwise @code{#f}.
@end deffn

@deffn {primitive procedure} slot-bound-using-class? class obj slot-name
Return @code{#t} if applying @code{slot-ref-using-class} to the same
arguments would call the generic function @code{slot-unbound}, otherwise
@code{#f}.

@code{slot-bound-using-class?} calls the generic function
@code{slot-missing} if @var{class} does not have a slot definition for a
slot called @var{slot-name} (@pxref{Accessing Slots,
slot-missing}).
@end deffn

@deffn {primitive procedure} slot-ref-using-class class obj slot-name
Apply the ``getter'' closure for the slot named @var{slot-name} in
@var{class} to @var{obj}, and return its result.

@code{slot-ref-using-class} calls the generic function
@code{slot-missing} if @var{class} does not have a slot definition for a
slot called @var{slot-name} (@pxref{Accessing Slots,
slot-missing}).

@code{slot-ref-using-class} calls the generic function
@code{slot-unbound} if the application of the ``getter'' closure to
@var{obj} returns an unbound value (@pxref{Accessing Slots,
slot-unbound}).
@end deffn

@deffn {primitive procedure} slot-set-using-class! class obj slot-name value
Apply the ``setter'' closure for the slot named @var{slot-name} in
@var{class} to @var{obj} and @var{value}.

@code{slot-set-using-class!} calls the generic function
@code{slot-missing} if @var{class} does not have a slot definition for a
slot called @var{slot-name} (@pxref{Accessing Slots, slot-missing}).
@end deffn

Slots whose allocation is per-class rather than per-instance can be
referenced and set without needing to specify any particular instance.

@deffn procedure class-slot-ref class slot-name
Return the value of the slot named @var{slot-name} in class @var{class}.
The named slot must have @code{#:class} or @code{#:each-subclass}
allocation (@pxref{Slot Options,, allocation}).

If there is no such slot with @code{#:class} or @code{#:each-subclass}
allocation, @code{class-slot-ref} calls the @code{slot-missing} generic
function with arguments @var{class} and @var{slot-name}.  Otherwise, if
the slot value is unbound, @code{class-slot-ref} calls the
@code{slot-unbound} generic function, with the same arguments.
@end deffn

@deffn procedure class-slot-set! class slot-name value
Set the value of the slot named @var{slot-name} in class @var{class} to
@var{value}.  The named slot must have @code{#:class} or
@code{#:each-subclass} allocation (@pxref{Slot Options,, allocation}).

If there is no such slot with @code{#:class} or @code{#:each-subclass}
allocation, @code{class-slot-ref} calls the @code{slot-missing} generic
function with arguments @var{class} and @var{slot-name}.
@end deffn

When a @code{slot-ref} or @code{slot-set!} call specifies a non-existent
slot name, or tries to reference a slot whose value is unbound, GOOPS
calls one of the following generic functions.

@deffn generic slot-missing
@deffnx method slot-missing (class <class>) slot-name
@deffnx method slot-missing (class <class>) (object <object>) slot-name
@deffnx method slot-missing (class <class>) (object <object>) slot-name value
When an application attempts to reference or set a class or instance
slot by name, and the slot name is invalid for the specified @var{class}
or @var{object}, GOOPS calls the @code{slot-missing} generic function.

The default methods all call @code{goops-error} with an appropriate
message.
@end deffn

@deffn generic slot-unbound
@deffnx method slot-unbound (object <object>)
@deffnx method slot-unbound (class <class>) slot-name
@deffnx method slot-unbound (class <class>) (object <object>) slot-name
When an application attempts to reference a class or instance slot, and
the slot's value is unbound, GOOPS calls the @code{slot-unbound} generic
function.

The default methods all call @code{goops-error} with an appropriate
message.
@end deffn


@node GOOPS Error Handling
@section Error Handling

The procedure @code{goops-error} is called to raise an appropriate error
by the default methods of the following generic functions:

@itemize @bullet
@item
@code{slot-missing} (@pxref{Accessing Slots,, slot-missing})

@item
@code{slot-unbound} (@pxref{Accessing Slots,, slot-unbound})

@item
@code{no-method} (@pxref{Handling Invocation Errors,, no-method})

@item
@code{no-applicable-method} (@pxref{Handling Invocation Errors,,
no-applicable-method})

@item
@code{no-next-method} (@pxref{Handling Invocation Errors,,
no-next-method})
@end itemize

If you customize these functions for particular classes or metaclasses,
you may still want to use @code{goops-error} to signal any error
conditions that you detect.

@deffn procedure goops-error format-string arg @dots{}
Raise an error with key @code{goops-error} and error message constructed
from @var{format-string} and @var{arg} @enddots{}.  Error message
formatting is as done by @code{scm-error}.
@end deffn


@node GOOPS Object Miscellany
@section GOOPS Object Miscellany

Here we cover some points about GOOPS objects that aren't substantial
enough to merit sections on their own.

@subheading Object Equality

When GOOPS is loaded, @code{eqv?}, @code{equal?} and @code{=} become
generic functions, and you can define methods for them, specialized for
your own classes, so as to control what the various kinds of equality
mean for your classes.

For example, the @code{assoc} procedure, for looking up an entry in an
alist, is specified as using @code{equal?} to determine when the car of
an entry in the alist is the same as the key parameter that @code{assoc}
is called with.  Hence, if you had defined a new class, and wanted to
use instances of that class as the keys in an alist, you could define a
method for @code{equal?}, for your class, to control @code{assoc}'s
lookup precisely.

@subheading Cloning Objects

@deffn generic shallow-clone
@deffnx method shallow-clone (self <object>)
Return a ``shallow'' clone of @var{self}.  The default method makes a
shallow clone by allocating a new instance and copying slot values from
self to the new instance.  Each slot value is copied either as an
immediate value or by reference.
@end deffn

@deffn generic deep-clone
@deffnx method deep-clone (self <object>)
Return a ``deep'' clone of @var{self}.  The default method makes a deep
clone by allocating a new instance and copying or cloning slot values
from self to the new instance.  If a slot value is an instance
(satisfies @code{instance?}), it is cloned by calling @code{deep-clone}
on that value.  Other slot values are copied either as immediate values
or by reference.
@end deffn

@subheading Write and Display

@deffn {primitive generic} write object port
@deffnx {primitive generic} display object port
When GOOPS is loaded, @code{write} and @code{display} become generic
functions with special methods for printing

@itemize @bullet
@item
objects - instances of the class @code{<object>}

@item
foreign objects - instances of the class @code{<foreign-object>}

@item
classes - instances of the class @code{<class>}

@item
generic functions - instances of the class @code{<generic>}

@item
methods - instances of the class @code{<method>}.
@end itemize

@code{write} and @code{display} print non-GOOPS values in the same way
as the Guile primitive @code{write} and @code{display} functions.
@end deffn

In addition to the cases mentioned, you can of course define
@code{write} and @code{display} methods for your own classes, to
customize how instances of those classes are printed.


@node The Metaobject Protocol
@section The Metaobject Protocol

At this point, we've said about as much as can be said about GOOPS
without having to confront the idea of the metaobject protocol.  There
are a couple more topics that could be discussed in isolation first ---
class redefinition, and changing the class of existing instances --- but
in practice developers using them will be advanced enough to want to
understand the metaobject protocol too, and will probably be using the
protocol to customize exactly what happens during these events.

So let's plunge in.  GOOPS is based on a ``metaobject protocol'' (aka
``MOP'') derived from the ones used in CLOS (the Common Lisp Object
System), tiny-clos (a small Scheme implementation of a subset of CLOS
functionality) and STKlos.

The MOP underlies many possible GOOPS customizations --- such as
defining an @code{initialize} method to customize the initialization of
instances of an application-defined class --- and an understanding of
the MOP makes it much easier to explain such customizations in a precise
way.  And at a deeper level, understanding the MOP is a key part of
understanding GOOPS, and of taking full advantage of GOOPS' power, by
customizing the behaviour of GOOPS itself.

@menu
* Metaobjects and the Metaobject Protocol::
* Metaclasses::
* MOP Specification::
* Instance Creation Protocol::
* Class Definition Protocol::
* Customizing Class Definition::
* Method Definition::
* Method Definition Internals::
* Generic Function Internals::
* Generic Function Invocation::
@end menu

@node Metaobjects and the Metaobject Protocol
@subsection Metaobjects and the Metaobject Protocol

The building blocks of GOOPS are classes, slot definitions, instances,
generic functions and methods.  A class is a grouping of inheritance
relations and slot definitions.  An instance is an object with slots
that are allocated following the rules implied by its class's
superclasses and slot definitions.  A generic function is a collection
of methods and rules for determining which of those methods to apply
when the generic function is invoked.  A method is a procedure and a set
of specializers that specify the type of arguments to which the
procedure is applicable.

Of these entities, GOOPS represents classes, generic functions and
methods as ``metaobjects''.  In other words, the values in a GOOPS
program that describe classes, generic functions and methods, are
themselves instances (or ``objects'') of special GOOPS classes that
encapsulate the behaviour, respectively, of classes, generic functions,
and methods.

(The other two entities are slot definitions and instances.  Slot
definitions are not strictly instances, but every slot definition is
associated with a GOOPS class that specifies the behaviour of the slot
as regards accessibility and protection from garbage collection.
Instances are of course objects in the usual sense, and there is no
benefit from thinking of them as metaobjects.)

The ``metaobject protocol'' (or ``MOP'') is the specification of the
generic functions which determine the behaviour of these metaobjects and
the circumstances in which these generic functions are invoked.

For a concrete example of what this means, consider how GOOPS calculates
the set of slots for a class that is being defined using
@code{define-class}.  The desired set of slots is the union of the new
class's direct slots and the slots of all its superclasses.  But
@code{define-class} itself does not perform this calculation.  Instead,
there is a method of the @code{initialize} generic function that is
specialized for instances of type @code{<class>}, and it is this method
that performs the slot calculation.

@code{initialize} is a generic function which GOOPS calls whenever a new
instance is created, immediately after allocating memory for a new
instance, in order to initialize the new instance's slots.  The sequence
of steps is as follows.

@itemize @bullet
@item
@code{define-class} uses @code{make} to make a new instance of the
@code{<class>} class, passing as initialization arguments the
superclasses, slot definitions and class options that were specified in
the @code{define-class} form.

@item
@code{make} allocates memory for the new instance, and invokes the
@code{initialize} generic function to initialize the new instance's
slots.

@item
The @code{initialize} generic function applies the method that is
specialized for instances of type @code{<class>}, and this method
performs the slot calculation.
@end itemize

In other words, rather than being hardcoded in @code{define-class}, the
default behaviour of class definition is encapsulated by generic
function methods that are specialized for the class @code{<class>}.

It is possible to create a new class that inherits from @code{<class>},
which is called a ``metaclass'', and to write a new @code{initialize}
method that is specialized for instances of the new metaclass.  Then, if
the @code{define-class} form includes a @code{#:metaclass} class option
whose value is the new metaclass, the class that is defined by the
@code{define-class} form will be an instance of the new metaclass rather
than of the default @code{<class>}, and will be defined in accordance
with the new @code{initialize} method.  Thus the default slot
calculation, as well as any other aspect of the new class's relationship
with its superclasses, can be modified or overridden.

In a similar way, the behaviour of generic functions can be modified or
overridden by creating a new class that inherits from the standard
generic function class @code{<generic>}, writing appropriate methods
that are specialized to the new class, and creating new generic
functions that are instances of the new class.

The same is true for method metaobjects.  And the same basic mechanism
allows the application class author to write an @code{initialize} method
that is specialized to their application class, to initialize instances
of that class.

Such is the power of the MOP.  Note that @code{initialize} is just one
of a large number of generic functions that can be customized to modify
the behaviour of application objects and classes and of GOOPS itself.
Each following section covers a particular area of GOOPS functionality,
and describes the generic functions that are relevant for customization
of that area.

@node Metaclasses
@subsection Metaclasses

A @dfn{metaclass} is the class of an object which represents a GOOPS
class.  Put more succinctly, a metaclass is a class's class.

Most GOOPS classes have the metaclass @code{<class>} and, by default,
any new class that is created using @code{define-class} has the
metaclass @code{<class>}.

But what does this really mean?  To find out, let's look in more detail
at what happens when a new class is created using @code{define-class}:

@example
(define-class <my-class> (<object>) . slots)
@end example

@noindent
Guile expands this to something like:

@example
(define <my-class> (class (<object>) . slots))
@end example

@noindent
which in turn expands to:

@example
(define <my-class>
  (make <class> #:dsupers (list <object>) #:slots slots))
@end example

As this expansion makes clear, the resulting value of @code{<my-class>}
is an instance of the class @code{<class>} with slot values specifying
the superclasses and slot definitions for the class @code{<my-class>}.
(@code{#:dsupers} and @code{#:slots} are initialization keywords for the
@code{dsupers} and @code{dslots} slots of the @code{<class>} class.)

Now suppose that you want to define a new class with a metaclass other
than the default @code{<class>}.  This is done by writing:

@example
(define-class <my-class2> (<object>)
   slot @dots{}
   #:metaclass <my-metaclass>)
@end example

@noindent
and Guile expands @emph{this} to something like:

@example
(define <my-class2>
  (make <my-metaclass> #:dsupers (list <object>) #:slots slots))
@end example

In this case, the value of @code{<my-class2>} is an instance of the more
specialized class @code{<my-metaclass>}.  Note that
@code{<my-metaclass>} itself must previously have been defined as a
subclass of @code{<class>}.  For a full discussion of when and how it is
useful to define new metaclasses, see @ref{MOP Specification}.

Now let's make an instance of @code{<my-class2>}:

@example
(define my-object (make <my-class2> ...))
@end example

All of the following statements are correct expressions of the
relationships between @code{my-object}, @code{<my-class2>},
@code{<my-metaclass>} and @code{<class>}.

@itemize @bullet
@item
@code{my-object} is an instance of the class @code{<my-class2>}.

@item
@code{<my-class2>} is an instance of the class @code{<my-metaclass>}.

@item
@code{<my-metaclass>} is an instance of the class @code{<class>}.

@item
The class of @code{my-object} is @code{<my-class2>}.

@item
The class of @code{<my-class2>} is @code{<my-metaclass>}.

@item
The class of @code{<my-metaclass>} is @code{<class>}.
@end itemize


@node MOP Specification
@subsection MOP Specification

The aim of the MOP specification in this chapter is to specify all the
customizable generic function invocations that can be made by the standard
GOOPS syntax, procedures and methods, and to explain the protocol for
customizing such invocations.

A generic function invocation is customizable if the types of the
arguments to which it is applied are not completely determined by the
lexical context in which the invocation appears.  For example, the
@code{(initialize @var{instance} @var{initargs})} invocation in the
default @code{make-instance} method is customizable, because the type of
the @code{@var{instance}} argument is determined by the class that was
passed to @code{make-instance}.

(Whereas --- to give a counter-example --- the @code{(make <generic>
#:name ',name)} invocation in @code{define-generic} is not customizable,
because all of its arguments have lexically determined types.)

When using this rule to decide whether a given generic function invocation
is customizable, we ignore arguments that are expected to be handled in
method definitions as a single ``rest'' list argument.

For each customizable generic function invocation, the @dfn{invocation
protocol} is explained by specifying

@itemize @bullet
@item
what, conceptually, the applied method is intended to do

@item
what assumptions, if any, the caller makes about the applied method's side
effects

@item
what the caller expects to get as the applied method's return value.
@end itemize


@node Instance Creation Protocol
@subsection Instance Creation Protocol

@code{make <class> . @var{initargs}} (method)

@itemize @bullet
@item
@code{allocate-instance @var{class} @var{initargs}} (generic)

The applied @code{allocate-instance} method should allocate storage for
a new instance of class @var{class} and return the uninitialized instance.

@item
@code{initialize @var{instance} @var{initargs}} (generic)

@var{instance} is the uninitialized instance returned by
@code{allocate-instance}.  The applied method should initialize the new
instance in whatever sense is appropriate for its class.  The method's
return value is ignored.
@end itemize

@code{make} itself is a generic function.  Hence the @code{make}
invocation itself can be customized in the case where the new instance's
metaclass is more specialized than the default @code{<class>}, by
defining a @code{make} method that is specialized to that metaclass.

Normally, however, the method for classes with metaclass @code{<class>}
will be applied.  This method calls two generic functions:

@itemize @bullet
@item
(allocate-instance @var{class} . @var{initargs})

@item
(initialize @var{instance} . @var{initargs})
@end itemize

@code{allocate-instance} allocates storage for and returns the new
instance, uninitialized.  You might customize @code{allocate-instance},
for example, if you wanted to provide a GOOPS wrapper around some other
object programming system.

To do this, you would create a specialized metaclass, which would act as
the metaclass for all classes and instances from the other system.  Then
define an @code{allocate-instance} method, specialized to that
metaclass, which calls a Guile primitive C function (or FFI code), which
in turn allocates the new instance using the interface of the other
object system.

In this case, for a complete system, you would also need to customize a
number of other generic functions like @code{make} and
@code{initialize}, so that GOOPS knows how to make classes from the
other system, access instance slots, and so on.

@code{initialize} initializes the instance that is returned by
@code{allocate-instance}.  The standard GOOPS methods perform
initializations appropriate to the instance class.

@itemize @bullet
@item
At the least specialized level, the method for instances of type
@code{<object>} performs internal GOOPS instance initialization, and
initializes the instance's slots according to the slot definitions and
any slot initialization keywords that appear in @var{initargs}.

@item
The method for instances of type @code{<class>} calls
@code{(next-method)}, then performs the class initializations described
in @ref{Class Definition Protocol}.

@item
and so on for generic functions, methods, operator classes @dots{}
@end itemize

Similarly, you can customize the initialization of instances of any
application-defined class by defining an @code{initialize} method
specialized to that class.

Imagine a class whose instances' slots need to be initialized at
instance creation time by querying a database.  Although it might be
possible to achieve this a combination of @code{#:init-thunk} keywords
and closures in the slot definitions, it may be neater to write an
@code{initialize} method for the class that queries the database once
and initializes all the dependent slot values according to the results.


@node Class Definition Protocol
@subsection Class Definition Protocol

Here is a summary diagram of the syntax, procedures and generic
functions that may be involved in class definition.

@noindent
@code{define-class} (syntax)

@itemize @bullet
@item
@code{class} (syntax)

@itemize @bullet
@item
@code{make-class} (procedure)

@itemize @bullet
@item
@code{ensure-metaclass} (procedure)

@item
@code{make @var{metaclass} @dots{}} (generic)

@itemize @bullet
@item
@code{allocate-instance} (generic)

@item
@code{initialize} (generic)

@itemize @bullet
@item
@code{compute-cpl} (generic)

@itemize @bullet
@item
@code{compute-std-cpl} (procedure)
@end itemize

@item
@code{compute-slots} (generic)

@item
@code{compute-get-n-set} (generic)

@item
@code{compute-getter-method} (generic)

@item
@code{compute-setter-method} (generic)
@end itemize
@end itemize
@end itemize
@end itemize

@item
@code{class-redefinition} (generic)

@itemize @bullet
@item
@code{remove-class-accessors} (generic)

@item
@code{update-direct-method!} (generic)

@item
@code{update-direct-subclass!} (generic)
@end itemize
@end itemize

Wherever a step above is marked as ``generic'', it can be customized,
and the detail shown below it is only ``correct'' insofar as it
describes what the default method of that generic function does.  For
example, if you write an @code{initialize} method, for some metaclass,
that does not call @code{next-method} and does not call
@code{compute-cpl}, then @code{compute-cpl} will not be called when a
class is defined with that metaclass. 

A @code{(define-class ...)} form (@pxref{Class Definition}) expands to
an expression which

@itemize @bullet
@item
checks that it is being evaluated only at top level

@item
defines any accessors that are implied by the @var{slot-definition}s

@item
uses @code{class} to create the new class

@item
checks for a previous class definition for @var{name} and, if found,
handles the redefinition by invoking @code{class-redefinition}
(@pxref{Redefining a Class}).
@end itemize

@deffn syntax class name (super @dots{}) @
              slot-definition @dots{} class-option @dots{}
Return a newly created class that inherits from @var{super}s, with
direct slots defined by @var{slot-definition}s and @var{class-option}s.
For the format of @var{slot-definition}s and @var{class-option}s, see
@ref{Class Definition,, define-class}.
@end deffn

@noindent @code{class} expands to an expression which

@itemize @bullet
@item
processes the class and slot definition options to check that they are
well-formed, to convert the @code{#:init-form} option to an
@code{#:init-thunk} option, to supply a default environment parameter
(the current top-level environment) and to evaluate all the bits that
need to be evaluated

@item
calls @code{make-class} to create the class with the processed and
evaluated parameters.
@end itemize

@deffn procedure make-class supers slots class-option @dots{}
Return a newly created class that inherits from @var{supers}, with
direct slots defined by @var{slots} and @var{class-option}s.  For the
format of @var{slots} and @var{class-option}s, see @ref{Class
Definition,, define-class}, except note that for @code{make-class},
@var{slots} is a separate list of slot definitions.
@end deffn

@noindent @code{make-class}

@itemize @bullet
@item
adds @code{<object>} to the @var{supers} list if @var{supers} is empty
or if none of the classes in @var{supers} have @code{<object>} in their
class precedence list

@item
defaults the @code{#:environment}, @code{#:name} and @code{#:metaclass}
options, if they are not specified by @var{options}, to the current
top-level environment, the unbound value, and @code{(ensure-metaclass
@var{supers})} respectively

@item
checks for duplicate classes in @var{supers} and duplicate slot names in
@var{slots}, and signals an error if there are any duplicates

@item
calls @code{make}, passing the metaclass as the first parameter and all
other parameters as option keywords with values.
@end itemize

@deffn procedure ensure-metaclass supers env
Return a metaclass suitable for a class that inherits from the list of
classes in @var{supers}.  The returned metaclass is the union by
inheritance of the metaclasses of the classes in @var{supers}.

In the simplest case, where all the @var{supers} are straightforward
classes with metaclass @code{<class>}, the returned metaclass is just
@code{<class>}.

For a more complex example, suppose that @var{supers} contained one
class with metaclass @code{<operator-class>} and one with metaclass
@code{<foreign-object-class>}.  Then the returned metaclass would be a
class that inherits from both @code{<operator-class>} and
@code{<foreign-object-class>}.

If @var{supers} is the empty list, @code{ensure-metaclass} returns the
default GOOPS metaclass @code{<class>}.

GOOPS keeps a list of the metaclasses created by
@code{ensure-metaclass}, so that each required type of metaclass only
has to be created once.

The @code{env} parameter is ignored.
@end deffn

@deffn generic make metaclass initarg @dots{}
@var{metaclass} is the metaclass of the class being defined, either
taken from the @code{#:metaclass} class option or computed by
@code{ensure-metaclass}.  The applied method must create and return the
fully initialized class metaobject for the new class definition.
@end deffn

The @code{(make @var{metaclass} @var{initarg} @dots{})} invocation is a
particular case of the instance creation protocol covered in the
previous section.  It will create an class metaobject with metaclass
@var{metaclass}.  By default, this metaobject will be initialized by the
@code{initialize} method that is specialized for instances of type
@code{<class>}.

The @code{initialize} method for classes (signature @code{(initialize
<class> initargs)}) calls the following generic functions.

@itemize @bullet
@item
@code{compute-cpl @var{class}} (generic)

The applied method should compute and return the class precedence list
for @var{class} as a list of class metaobjects.  When @code{compute-cpl}
is called, the following @var{class} metaobject slots have all been
initialized: @code{name}, @code{direct-supers}, @code{direct-slots},
@code{direct-subclasses} (empty), @code{direct-methods}.  The value
returned by @code{compute-cpl} will be stored in the @code{cpl} slot.

@item
@code{compute-slots @var{class}} (generic)

The applied method should compute and return the slots (union of direct
and inherited) for @var{class} as a list of slot definitions.  When
@code{compute-slots} is called, all the @var{class} metaobject slots
mentioned for @code{compute-cpl} have been initialized, plus the
following: @code{cpl}, @code{redefined} (@code{#f}), @code{environment}.
The value returned by @code{compute-slots} will be stored in the
@code{slots} slot.

@item
@code{compute-get-n-set @var{class} @var{slot-def}} (generic)

@code{initialize} calls @code{compute-get-n-set} for each slot computed
by @code{compute-slots}.  The applied method should compute and return a
pair of closures that, respectively, get and set the value of the specified
slot.  The get closure should have arity 1 and expect a single argument
that is the instance whose slot value is to be retrieved.  The set closure
should have arity 2 and expect two arguments, where the first argument is
the instance whose slot value is to be set and the second argument is the
new value for that slot.  The closures should be returned in a two element
list: @code{(list @var{get} @var{set})}.

The closures returned by @code{compute-get-n-set} are stored as part of
the value of the @var{class} metaobject's @code{getters-n-setters} slot.
Specifically, the value of this slot is a list with the same number of
elements as there are slots in the class, and each element looks either like

@example
@code{(@var{slot-name-symbol} @var{init-function} . @var{index})}
@end example

or like

@example
@code{(@var{slot-name-symbol} @var{init-function} @var{get} @var{set})}
@end example

Where the get and set closures are replaced by @var{index}, the slot is
an instance slot and @var{index} is the slot's index in the underlying
structure: GOOPS knows how to get and set the value of such slots and so
does not need specially constructed get and set closures.  Otherwise,
@var{get} and @var{set} are the closures returned by @code{compute-get-n-set}.

The structure of the @code{getters-n-setters} slot value is important when
understanding the next customizable generic functions that @code{initialize}
calls@dots{}

@item
@code{compute-getter-method @var{class} @var{gns}} (generic)

@code{initialize} calls @code{compute-getter-method} for each of the
class's slots (as determined by @code{compute-slots}) that includes a
@code{#:getter} or @code{#:accessor} slot option.  @var{gns} is the
element of the @var{class} metaobject's @code{getters-n-setters} slot
that specifies how the slot in question is referenced and set, as
described above under @code{compute-get-n-set}.  The applied method
should create and return a method that is specialized for instances of
type @var{class} and uses the get closure to retrieve the slot's value.
@code{initialize} uses @code{add-method!} to add the returned method to
the generic function named by the slot definition's @code{#:getter} or
@code{#:accessor} option.

@item
@code{compute-setter-method @var{class} @var{gns}} (generic)

@code{compute-setter-method} is invoked with the same arguments as
@code{compute-getter-method}, for each of the class's slots that includes
a @code{#:setter} or @code{#:accessor} slot option.  The applied method
should create and return a method that is specialized for instances of
type @var{class} and uses the set closure to set the slot's value.
@code{initialize} then uses @code{add-method!} to add the returned method
to the generic function named by the slot definition's @code{#:setter}
or @code{#:accessor} option.
@end itemize

@node Customizing Class Definition
@subsection Customizing Class Definition

If the metaclass of the new class is something more specialized than the
default @code{<class>}, then the type of @var{class} in the calls above
is more specialized than @code{<class>}, and hence it becomes possible
to define generic function methods, specialized for the new class's
metaclass, that can modify or override the default behaviour of
@code{initialize}, @code{compute-cpl} or @code{compute-get-n-set}.

@code{compute-cpl} computes the class precedence list (``CPL'') for the
new class (@pxref{Class Precedence List}), and returns it as a list of
class objects.  The CPL is important because it defines a superclass
ordering that is used, when a generic function is invoked upon an
instance of the class, to decide which of the available generic function
methods is the most specific.  Hence @code{compute-cpl} could be
customized in order to modify the CPL ordering algorithm for all classes
with a special metaclass.

The default CPL algorithm is encapsulated by the @code{compute-std-cpl}
procedure, which is called by the default @code{compute-cpl} method.

@deffn procedure compute-std-cpl class
Compute and return the class precedence list for @var{class} according
to the algorithm described in @ref{Class Precedence List}.
@end deffn

@code{compute-slots} computes and returns a list of all slot definitions
for the new class.  By default, this list includes the direct slot
definitions from the @code{define-class} form, plus the slot definitions
that are inherited from the new class's superclasses.  The default
@code{compute-slots} method uses the CPL computed by @code{compute-cpl}
to calculate this union of slot definitions, with the rule that slots
inherited from superclasses are shadowed by direct slots with the same
name.  One possible reason for customizing @code{compute-slots} would be
to implement an alternative resolution strategy for slot name conflicts.

@code{compute-get-n-set} computes the low-level closures that will be
used to get and set the value of a particular slot, and returns them in
a list with two elements.

The closures returned depend on how storage for that slot is allocated.
The standard @code{compute-get-n-set} method, specialized for classes of
type @code{<class>}, handles the standard GOOPS values for the
@code{#:allocation} slot option (@pxref{Slot Options,, allocation}).  By
defining a new @code{compute-get-n-set} method for a more specialized
metaclass, it is possible to support new types of slot allocation.

Suppose you wanted to create a large number of instances of some class
with a slot that should be shared between some but not all instances of
that class - say every 10 instances should share the same slot storage.
The following example shows how to implement and use a new type of slot
allocation to do this.

@example
(define-class <batched-allocation-metaclass> (<class>))

(let ((batch-allocation-count 0)
      (batch-get-n-set #f))
  (define-method (compute-get-n-set
                     (class <batched-allocation-metaclass>) s)
    (case (slot-definition-allocation s)
      ((#:batched)
       ;; If we've already used the same slot storage for 10 instances,
       ;; reset variables.
       (if (= batch-allocation-count 10)
           (begin
             (set! batch-allocation-count 0)
             (set! batch-get-n-set #f)))
       ;; If we don't have a current pair of get and set closures,
       ;; create one.  make-closure-variable returns a pair of closures
       ;; around a single Scheme variable - see goops.scm for details.
       (or batch-get-n-set
           (set! batch-get-n-set (make-closure-variable)))
       ;; Increment the batch allocation count.
       (set! batch-allocation-count (+ batch-allocation-count 1))
       batch-get-n-set)

      ;; Call next-method to handle standard allocation types.
      (else (next-method)))))

(define-class <class-using-batched-slot> ()
  ...
  (c #:allocation #:batched)
  ...
  #:metaclass <batched-allocation-metaclass>)
@end example

The usage of @code{compute-getter-method} and @code{compute-setter-method}
is described in @ref{Class Definition Protocol}.

@code{compute-cpl} and @code{compute-get-n-set} are called by the
standard @code{initialize} method for classes whose metaclass is
@code{<class>}.  But @code{initialize} itself can also be modified, by
defining an @code{initialize} method specialized to the new class's
metaclass.  Such a method could complete override the standard
behaviour, by not calling @code{(next-method)} at all, but more
typically it would perform additional class initialization steps before
and/or after calling @code{(next-method)} for the standard behaviour.


@node Method Definition
@subsection Method Definition

@code{define-method} (syntax)

@itemize @bullet
@item
@code{add-method! @var{target} @var{method}} (generic)
@end itemize

@noindent
@code{define-method} invokes the @code{add-method!} generic function to
handle adding the new method to a variety of possible targets.  GOOPS
includes methods to handle @var{target} as

@itemize @bullet
@item
a generic function (the most common case)

@item
a procedure

@item
a primitive generic (@pxref{Extending Primitives})
@end itemize

By defining further methods for @code{add-method!}, you can
theoretically handle adding methods to further types of target.


@node Method Definition Internals
@subsection Method Definition Internals

@code{define-method}:

@itemize @bullet
@item
checks the form of the first parameter, and applies the following steps
to the accessor's setter if it has the @code{(setter @dots{})} form

@item
interpolates a call to @code{define-generic} or @code{define-accessor}
if a generic function is not already defined with the supplied name

@item
calls @code{method} with the @var{parameter}s and @var{body}, to make a
new method instance

@item
calls @code{add-method!} to add this method to the relevant generic
function.
@end itemize

@deffn syntax method (parameter @dots{}) body @dots{}
Make a method whose specializers are defined by the classes in
@var{parameter}s and whose procedure definition is constructed from the
@var{parameter} symbols and @var{body} forms.

The @var{parameter} and @var{body} parameters should be as for
@code{define-method} (@pxref{Methods and Generic Functions,,
define-method}).
@end deffn

@noindent
@code{method}:

@itemize @bullet
@item
extracts formals and specializing classes from the @var{parameter}s,
defaulting the class for unspecialized parameters to @code{<top>}

@item
creates a closure using the formals and the @var{body} forms

@item
calls @code{make} with metaclass @code{<method>} and the specializers
and closure using the @code{#:specializers} and @code{#:procedure}
keywords.
@end itemize

@deffn procedure make-method specializers procedure
Make a method using @var{specializers} and @var{procedure}.

@var{specializers} should be a list of classes that specifies the
parameter combinations to which this method will be applicable.

@var{procedure} should be the closure that will applied to the generic
function parameters when this method is invoked.
@end deffn

@noindent
@code{make-method} is a simple wrapper around @code{make} with metaclass
@code{<method>}.

@deffn generic add-method! target method
Generic function for adding method @var{method} to @var{target}.
@end deffn

@deffn method add-method! (generic <generic>) (method <method>)
Add method @var{method} to the generic function @var{generic}.
@end deffn

@deffn method add-method! (proc <procedure>) (method <method>)
If @var{proc} is a procedure with generic capability (@pxref{Extending
Primitives,, generic-capability?}), upgrade it to a primitive generic
and add @var{method} to its generic function definition.
@end deffn

@deffn method add-method! (pg <primitive-generic>) (method <method>)
Add method @var{method} to the generic function definition of @var{pg}.

Implementation: @code{(add-method! (primitive-generic-generic pg) method)}.
@end deffn

@deffn method add-method! (whatever <top>) (method <method>)
Raise an error indicating that @var{whatever} is not a valid generic
function.
@end deffn

@node Generic Function Internals
@subsection Generic Function Internals

@code{define-generic} calls @code{ensure-generic} to upgrade a
pre-existing procedure value, or @code{make} with metaclass
@code{<generic>} to create a new generic function.

@code{define-accessor} calls @code{ensure-accessor} to upgrade a
pre-existing procedure value, or @code{make-accessor} to create a new
accessor.

@deffn procedure ensure-generic old-definition [name]
Return a generic function with name @var{name}, if possible by using or
upgrading @var{old-definition}.  If unspecified, @var{name} defaults to
@code{#f}.

If @var{old-definition} is already a generic function, it is returned
unchanged.

If @var{old-definition} is a Scheme procedure or procedure-with-setter,
@code{ensure-generic} returns a new generic function that uses
@var{old-definition} for its default procedure and setter.

Otherwise @code{ensure-generic} returns a new generic function with no
defaults and no methods.
@end deffn

@deffn procedure make-generic [name]
Return a new generic function with name @code{(car @var{name})}.  If
unspecified, @var{name} defaults to @code{#f}.
@end deffn

@code{ensure-generic} calls @code{make} with metaclasses
@code{<generic>} and @code{<generic-with-setter>}, depending on the
previous value of the variable that it is trying to upgrade.

@code{make-generic} is a simple wrapper for @code{make} with metaclass
@code{<generic>}.

@deffn procedure ensure-accessor proc [name]
Return an accessor with name @var{name}, if possible by using or
upgrading @var{proc}.  If unspecified, @var{name} defaults to @code{#f}.

If @var{proc} is already an accessor, it is returned unchanged.

If @var{proc} is a Scheme procedure, procedure-with-setter or generic
function, @code{ensure-accessor} returns an accessor that reuses the
reusable elements of @var{proc}.

Otherwise @code{ensure-accessor} returns a new accessor with no defaults
and no methods.
@end deffn

@deffn procedure make-accessor [name]
Return a new accessor with name @code{(car @var{name})}.  If
unspecified, @var{name} defaults to @code{#f}.
@end deffn

@code{ensure-accessor} calls @code{make} with
metaclass @code{<generic-with-setter>}, as well as calls to
@code{ensure-generic}, @code{make-accessor} and (tail recursively)
@code{ensure-accessor}.

@code{make-accessor} calls @code{make} twice, first
with metaclass @code{<generic>} to create a generic function for the
setter, then with metaclass @code{<generic-with-setter>} to create the
accessor, passing the setter generic function as the value of the
@code{#:setter} keyword.

@node Generic Function Invocation
@subsection Generic Function Invocation

There is a detailed and customizable protocol involved in the process of
invoking a generic function --- i.e., in the process of deciding which
of the generic function's methods are applicable to the current
arguments, and which one of those to apply.  Here is a summary diagram
of the generic functions involved.

@noindent
@code{apply-generic} (generic)

@itemize @bullet
@item
@code{no-method} (generic)

@item
@code{compute-applicable-methods} (generic)

@item
@code{sort-applicable-methods} (generic)

@itemize @bullet
@item
@code{method-more-specific?} (generic)
@end itemize

@item
@code{apply-methods} (generic)

@itemize @bullet
@item
@code{apply-method} (generic)

@item
@code{no-next-method} (generic)
@end itemize

@item
@code{no-applicable-method}
@end itemize

We do not yet have full documentation for these.  Please refer to the
code (@file{oop/goops.scm}) for details.


@node Redefining a Class
@section Redefining a Class

Suppose that a class @code{<my-class>} is defined using @code{define-class}
(@pxref{Class Definition,, define-class}), with slots that have
accessor functions, and that an application has created several instances
of @code{<my-class>} using @code{make} (@pxref{Instance Creation,,
make}).  What then happens if @code{<my-class>} is redefined by calling
@code{define-class} again?

@menu
* Redefinable Classes::
* Default Class Redefinition Behaviour::
* Customizing Class Redefinition::
@end menu

@node Redefinable Classes
@subsection Redefinable Classes

The ability for a class to be redefined is a choice for a class author
to make.  By default, classes in GOOPS are @emph{not} redefinable.  A
redefinable class is an instance of @code{<redefinable-class>}; that is
to say, a class with @code{<redefinable-class>} as its metaclass.
Accordingly, to define a redefinable class, add @code{#:metaclass
<redefinable-class>} to its class definition:

@example
(define-class <foo> ()
  #:metaclass <redefinable-class>)
@end example

Note that any subclass of @code{<foo>} is also redefinable, without the
need to explicitly pass the @code{#:metaclass} argument, so you only
need to specify @code{#:metaclass} for the roots of your application's
class hierarchy.

@example
(define-class <bar> (<foo>))
(class-of <bar>) @result{} <redefinable-class>
@end example

Note that prior to Guile 3.0, all GOOPS classes were redefinable in
theory.  In practice, attempting to, for example, redefine
@code{<class>} itself would almost certainly not do what you want.
Still, redefinition is an interesting capability when building
long-lived resilient systems, so GOOPS does offer this facility.

@node Default Class Redefinition Behaviour
@subsection Default Class Redefinition Behaviour

When a class is defined using @code{define-class} and the class name was
previously defined, by default the new binding just replaces the old
binding.  This is the normal behavior for @code{define}.  However if
both the old and new bindings are redefinable classes (instances of
@code{<redefinable-class>}), then the class will be updated in place,
and its instances lazily migrated over.

The way that the class is updated and the way that the instances migrate
over are of course part of the meta-object protocol.  However the
default behavior usually suffices, and it goes as follows.

@itemize @bullet
@item
All existing direct instances of @code{<my-class>} are converted to be
instances of the new class.  This is achieved by preserving the values
of slots that exist in both the old and new definitions, and
initializing the values of new slots in the usual way (@pxref{Instance
Creation,, make}).

@item
All existing subclasses of @code{<my-class>} are redefined, as though
the @code{define-class} expressions that defined them were re-evaluated
following the redefinition of @code{<my-class>}, and the class
redefinition process described here is applied recursively to the
redefined subclasses.

@item
Once all of its instances and subclasses have been updated, the class
metaobject previously bound to the variable @code{<my-class>} is no
longer needed and so can be allowed to be garbage collected.
@end itemize

To keep things tidy, GOOPS also needs to do a little housekeeping on
methods that are associated with the redefined class.

@itemize @bullet
@item
Slot accessor methods for slots in the old definition should be removed
from their generic functions.  They will be replaced by accessor methods
for the slots of the new class definition.

@item
Any generic function method that uses the old @code{<my-class>} metaobject
as one of its formal parameter specializers must be updated to refer to
the new @code{<my-class>} metaobject.  (Whenever a new generic function
method is defined, @code{define-method} adds the method to a list stored
in the class metaobject for each class used as a formal parameter
specializer, so it is easy to identify all the methods that must be
updated when a class is redefined.)
@end itemize

If this class redefinition strategy strikes you as rather counter-intuitive,
bear in mind that it is derived from similar behaviour in other object
systems such as CLOS, and that experience in those systems has shown it to be
very useful in practice.

Also bear in mind that, like most of GOOPS' default behaviour, it can
be customized@dots{}

@node Customizing Class Redefinition
@subsection Customizing Class Redefinition

When @code{define-class} notices that a class is being redefined, it
constructs the new class metaobject as usual, then invokes the
@code{class-redefinition} generic function with the old and new classes
as arguments.  Therefore, if the old or new classes have metaclasses
other than the default @code{<redefinable-class>}, class redefinition
behaviour can be customized by defining a @code{class-redefinition}
method that is specialized for the relevant metaclasses.

@deffn generic class-redefinition
Handle the class redefinition from @var{old} to @var{new}, and return
the new class metaobject that should be bound to the variable specified
by @code{define-class}'s first argument.
@end deffn

@deffn method class-redefinition (old <top>) (new <class>)
Not all classes are redefinable, and not all previous bindings are
classes.  @xref{Redefinable Classes}.  This default method just returns
@var{new}.
@end deffn

@deffn method class-redefinition (old <redefinable-class>) (new <redefinable-class>)
This method implements GOOPS' default class redefinition behaviour, as
described in @ref{Default Class Redefinition Behaviour}.  Returns the
metaobject for the new class definition.
@end deffn

The @code{class-redefinition} method for classes with metaclass
@code{<redefinable-class>} calls the following generic functions, which
could of course be individually customized.

@deffn generic remove-class-accessors! old
The default @code{remove-class-accessors!} method removes the accessor
methods of the old class from all classes which they specialize.
@end deffn

@deffn generic update-direct-method! method old new
The default @code{update-direct-method!} method substitutes the new
class for the old in all methods specialized to the old class.
@end deffn

@deffn generic update-direct-subclass! subclass old new
The default @code{update-direct-subclass!} method invokes
@code{class-redefinition} recursively to handle the redefinition of
subclasses.
@end deffn

An alternative class redefinition strategy could be to leave all
existing instances as instances of the old class, but accepting that the
old class is now ``nameless'', since its name has been taken over by the
new definition.  In this strategy, any existing subclasses could also
be left as they are, on the understanding that they inherit from a nameless
superclass.

This strategy is easily implemented in GOOPS, by defining a new metaclass,
that will be used as the metaclass for all classes to which the strategy
should apply, and then defining a @code{class-redefinition} method that
is specialized for this metaclass:

@example
(define-class <can-be-nameless> (<redefinable-class>))

(define-method (class-redefinition (old <can-be-nameless>)
                                   (new <class>))
  new)
@end example

When customization can be as easy as this, aren't you glad that GOOPS
implements the far more difficult strategy as its default!


@node Changing the Class of an Instance
@section Changing the Class of an Instance

When a redefinable class is redefined, any existing instance of the
redefined class will be modified for the new class definition before the
next time that any of the instance's slots is referenced or set.  GOOPS
modifies each instance by calling the generic function
@code{change-class}.

More generally, you can change the class of an existing instance at any
time by invoking the generic function @code{change-class} with two
arguments: the instance and the new class.

The default method for @code{change-class} decides how to implement the
change of class by looking at the slot definitions for the instance's
existing class and for the new class.  If the new class has slots with
the same name as slots in the existing class, the values for those slots
are preserved.  Slots that are present only in the existing class are
discarded.  Slots that are present only in the new class are initialized
using the corresponding slot definition's init function (@pxref{Classes,,
slot-init-function}).

@deffn generic change-class instance new-class
@end deffn

@deffn {method} change-class (obj <object>) (new <redefinable-class>)
Modify instance @var{obj} to make it an instance of class @var{new}.
@var{obj} itself must already be an instance of a redefinable class.

The value of each of @var{obj}'s slots is preserved only if a similarly named
slot exists in @var{new}; any other slot values are discarded.

The slots in @var{new} that do not correspond to any of @var{obj}'s
pre-existing slots are initialized according to @var{new}'s slot definitions'
init functions.
@end deffn

The default @code{change-class} method also invokes another generic
function, @code{update-instance-for-different-class}, as the last thing
that it does before returning.  The applied
@code{update-instance-for-different-class} method can make any further
adjustments to @var{new-instance} that are required to complete or
modify the change of class.  The return value from the applied method is
ignored.

@deffn generic update-instance-for-different-class old-instance new-instance
A generic function that can be customized to put finishing touches to an
instance whose class has just been changed.  The default
@code{update-instance-for-different-class} method does nothing.
@end deffn

Customized change of class behaviour can be implemented by defining
@code{change-class} methods that are specialized either by the class
of the instances to be modified or by the metaclass of the new class.