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 2986 2987 2988 2989 2990 2991 2992 2993 2994 2995 2996 2997 2998 2999 3000 3001 3002 3003 3004 3005 3006 3007 3008 3009 3010 3011 3012 3013 3014 3015 3016 3017 3018 3019 3020 3021 3022 3023 3024 3025 3026 3027 3028 3029 3030 3031 3032 3033 3034 3035 3036 3037 3038 3039 3040 3041 3042 3043 3044 3045 3046 3047 3048 3049 3050 3051 3052 3053 3054 3055 3056 3057 3058 3059 3060 3061 3062 3063 3064 3065 3066 3067 3068 3069 3070 3071 3072 3073 3074 3075 3076 3077 3078 3079 3080 3081 3082 3083 3084 3085 3086 3087 3088 3089 3090 3091 3092 3093 3094 3095 3096 3097 3098 3099 3100 3101 3102 3103 3104 3105 3106 3107 3108 3109 3110 3111 3112 3113 3114 3115 3116 3117 3118 3119 3120 3121 3122 3123 3124 3125 3126 3127 3128 3129 3130 3131 3132 3133 3134 3135 3136 3137 3138 3139 3140 3141 3142 3143 3144 3145 3146 3147 3148 3149 3150 3151 3152 3153 3154 3155 3156 3157 3158 3159 3160 3161 3162 3163 3164 3165 3166 3167 3168 3169 3170 3171 3172 3173 3174 3175 3176 3177 3178 3179 3180 3181 3182 3183 3184 3185 3186 3187 3188 3189 3190 3191 3192 3193 3194 3195 3196 3197 3198 3199 3200 3201 3202 3203 3204 3205 3206 3207 3208 3209 3210 3211 3212 3213 3214 3215 3216 3217 3218 3219 3220 3221 3222 3223 3224 3225 3226 3227 3228 3229 3230 3231 3232 3233 3234 3235 3236 3237 3238 3239 3240 3241 3242 3243 3244 3245 3246 3247 3248 3249 3250 3251 3252 3253 3254 3255 3256 3257 3258 3259 3260 3261 3262 3263 3264 3265 3266 3267 3268 3269 3270 3271 3272 3273 3274 3275 3276 3277 3278 3279 3280 3281 3282 3283 3284 3285 3286 3287 3288 3289 3290 3291 3292 3293 3294 3295 3296 3297 3298 3299 3300 3301 3302 3303 3304 3305 3306 3307 3308 3309 3310 3311 3312 3313 3314 3315 3316 3317 3318 3319 3320 3321 3322 3323 3324 3325 3326 3327 3328 3329 3330 3331 3332 3333 3334 3335 3336 3337 3338 3339 3340 3341 3342 3343 3344 3345 3346 3347 3348 3349 3350 3351 3352 3353 3354 3355 3356 3357 3358 3359 3360 3361 3362 3363 3364 3365 3366 3367 3368 3369 3370 3371 3372 3373 3374 3375 3376 3377 3378 3379 3380 3381 3382 3383 3384 3385 3386 3387 3388 3389 3390 3391 3392 3393 3394 3395 3396 3397 3398 3399 3400 3401 3402 3403 3404 3405 3406 3407 3408 3409 3410 3411 3412 3413 3414 3415 3416 3417 3418 3419 3420 3421 3422 3423 3424 3425 3426 3427 3428 3429 3430 3431 3432 3433 3434 3435 3436 3437 3438 3439 3440 3441 3442 3443 3444 3445 3446 3447 3448 3449 3450 3451 3452 3453 3454 3455 3456 3457 3458 3459 3460 3461 3462 3463 3464 3465 3466 3467 3468 3469 3470 3471 3472 3473 3474 3475 3476 3477 3478 3479 3480 3481 3482 3483 3484 3485 3486 3487 3488 3489 3490 3491 3492 3493 3494 3495 3496 3497 3498 3499 3500 3501 3502 3503 3504 3505 3506 3507 3508 3509 3510 3511 3512 3513 3514 3515 3516 3517 3518 3519 3520 3521 3522 3523 3524 3525 3526 3527 3528 3529 3530 3531 3532 3533 3534 3535 3536 3537 3538 3539 3540 3541 3542 3543 3544 3545 3546 3547 3548 3549 3550 3551 3552 3553 3554 3555 3556 3557 3558 3559 3560 3561 3562 3563 3564 3565 3566 3567 3568 3569 3570 3571 3572 3573 3574 3575 3576 3577 3578 3579 3580 3581 3582 3583 3584 3585 3586 3587 3588 3589 3590 3591 3592 3593 3594 3595 3596 3597 3598 3599 3600 3601 3602 3603 3604 3605 3606 3607 3608 3609 3610 3611 3612 3613 3614 3615 3616 3617 3618 3619 3620 3621 3622 3623 3624 3625 3626 3627 3628 3629 3630 3631 3632 3633 3634 3635 3636 3637 3638 3639 3640 3641 3642 3643 3644 3645 3646 3647 3648 3649 3650 3651 3652 3653 3654 3655 3656 3657 3658 3659 3660 3661 3662 3663 3664 3665 3666 3667 3668 3669 3670 3671 3672 3673 3674 3675 3676 3677 3678 3679 3680 3681 3682 3683 3684 3685 3686 3687 3688 3689 3690 3691 3692 3693 3694 3695 3696 3697 3698 3699 3700 3701 3702 3703 3704 3705 3706 3707 3708 3709 3710 3711 3712 3713 3714 3715 3716 3717 3718 3719 3720 3721 3722 3723 3724 3725 3726 3727 3728 3729 3730 3731 3732 3733 3734 3735 3736 3737 3738 3739 3740 3741 3742 3743 3744 3745 3746 3747 3748 3749 3750 3751 3752 3753 3754 3755 3756 3757 3758 3759 3760 3761 3762 3763 3764 3765 3766 3767 3768 3769 3770 3771 3772 3773 3774 3775 3776 3777 3778 3779 3780 3781 3782 3783 3784 3785 3786 3787 3788 3789 3790 3791 3792 3793 3794 3795 3796 3797 3798 3799 3800 3801 3802 3803 3804 3805 3806 3807 3808 3809 3810 3811 3812 3813 3814 3815 3816 3817 3818 3819 3820 3821 3822 3823 3824 3825 3826 3827 3828 3829 3830 3831 3832 3833 3834 3835 3836 3837 3838 3839 3840 3841 3842 3843 3844 3845 3846 3847 3848 3849 3850 3851 3852 3853 3854 3855 3856 3857 3858 3859 3860 3861 3862 3863 3864 3865 3866 3867 3868 3869 3870 3871 3872 3873 3874 3875 3876 3877 3878 3879 3880 3881 3882 3883 3884 3885 3886 3887 3888 3889 3890 3891 3892 3893 3894 3895 3896 3897 3898 3899 3900 3901 3902 3903 3904 3905 3906 3907 3908 3909 3910 3911 3912 3913 3914 3915 3916 3917 3918 3919 3920 3921 3922 3923 3924 3925 3926 3927 3928 3929 3930 3931 3932 3933 3934 3935 3936 3937 3938 3939 3940 3941 3942 3943 3944 3945 3946 3947 3948 3949 3950 3951 3952 3953 3954 3955 3956 3957 3958 3959 3960 3961 3962 3963 3964 3965 3966 3967 3968 3969 3970 3971 3972 3973 3974 3975 3976 3977 3978 3979 3980 3981 3982 3983 3984 3985 3986 3987 3988 3989 3990 3991 3992 3993 3994 3995 3996 3997 3998 3999 4000 4001 4002 4003 4004 4005 4006 4007 4008 4009 4010 4011 4012 4013 4014 4015 4016 4017 4018 4019 4020 4021 4022 4023 4024 4025 4026 4027 4028 4029 4030 4031 4032 4033 4034 4035 4036 4037 4038 4039 4040 4041 4042 4043 4044 4045 4046 4047 4048 4049 4050 4051 4052 4053 4054 4055 4056 4057 4058 4059 4060 4061 4062 4063 4064 4065 4066 4067 4068 4069 4070 4071 4072 4073 4074 4075 4076 4077 4078 4079 4080 4081 4082 4083 4084 4085 4086 4087 4088 4089 4090 4091 4092 4093 4094 4095 4096 4097 4098 4099 4100 4101 4102 4103 4104 4105 4106 4107 4108 4109 4110 4111 4112 4113 4114 4115 4116 4117 4118 4119 4120 4121 4122 4123 4124 4125 4126 4127 4128 4129 4130 4131 4132 4133 4134 4135 4136 4137 4138 4139 4140 4141 4142 4143 4144 4145 4146 4147 4148 4149 4150 4151 4152 4153 4154 4155 4156 4157 4158 4159 4160 4161 4162 4163 4164 4165 4166 4167 4168 4169 4170 4171 4172 4173 4174 4175 4176 4177 4178 4179 4180 4181 4182 4183 4184 4185 4186 4187 4188 4189 4190 4191 4192 4193 4194 4195 4196 4197 4198 4199 4200 4201 4202 4203 4204 4205 4206 4207 4208 4209 4210 4211 4212 4213 4214 4215 4216 4217 4218 4219 4220 4221 4222 4223 4224 4225 4226 4227 4228 4229 4230 4231 4232 4233 4234 4235 4236 4237 4238 4239 4240 4241 4242 4243 4244 4245 4246 4247 4248 4249 4250 4251 4252 4253 4254 4255 4256 4257 4258 4259 4260 4261 4262 4263 4264 4265 4266 4267 4268 4269 4270 4271 4272 4273 4274 4275 4276 4277 4278 4279 4280 4281 4282 4283 4284 4285 4286 4287 4288 4289 4290 4291 4292 4293 4294 4295 4296 4297 4298 4299 4300 4301 4302 4303 4304 4305 4306 4307 4308 4309 4310 4311 4312 4313 4314 4315 4316 4317 4318 4319 4320 4321 4322 4323 4324 4325 4326 4327 4328 4329 4330 4331 4332 4333 4334 4335 4336 4337 4338 4339 4340 4341 4342 4343 4344 4345 4346 4347 4348 4349 4350 4351 4352 4353 4354 4355 4356 4357 4358 4359 4360 4361 4362 4363 4364 4365 4366 4367 4368 4369 4370 4371 4372 4373 4374 4375 4376 4377 4378 4379 4380 4381 4382 4383 4384 4385 4386 4387 4388 4389 4390 4391 4392 4393 4394 4395 4396 4397 4398 4399 4400 4401 4402 4403 4404 4405 4406 4407 4408 4409 4410 4411 4412 4413 4414 4415 4416 4417 4418 4419 4420 4421 4422 4423 4424 4425 4426 4427 4428 4429 4430 4431 4432 4433 4434 4435 4436 4437 4438 4439 4440 4441 4442 4443 4444 4445 4446 4447 4448 4449 4450 4451 4452 4453 4454 4455 4456 4457 4458 4459 4460 4461 4462 4463 4464 4465 4466 4467 4468 4469 4470 4471 4472 4473 4474 4475 4476 4477 4478 4479 4480 4481 4482 4483 4484 4485 4486 4487 4488 4489 4490 4491 4492 4493 4494 4495 4496 4497 4498 4499 4500 4501 4502 4503 4504 4505 4506 4507 4508 4509 4510 4511 4512 4513 4514 4515 4516 4517 4518 4519 4520 4521 4522 4523 4524 4525 4526 4527 4528 4529 4530 4531 4532 4533 4534 4535 4536 4537 4538 4539 4540 4541 4542 4543 4544 4545 4546 4547 4548 4549 4550 4551 4552 4553 4554 4555 4556 4557 4558 4559 4560 4561 4562 4563 4564 4565 4566 4567 4568 4569 4570 4571 4572 4573 4574 4575 4576 4577 4578 4579
|
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<!--
Generated from mzscheme.tex by tex2page, v 20050501
(running on MzScheme 352, unix),
(c) Dorai Sitaram,
http://www.ccs.neu.edu/~dorai/tex2page/tex2page-doc.html
-->
<head>
<title>
PLT MzScheme: Language Manual
</title>
<link rel="stylesheet" type="text/css" href="mzscheme-Z-S.css" title=default>
<meta name=robots content="noindex,follow">
</head>
<body>
<div id=content>
<div align=right class=navigation><i>[Go to <span><a href="mzscheme.html">first</a>, <a href="mzscheme-Z-H-10.html">previous</a></span><span>, <a href="mzscheme-Z-H-12.html">next</a></span> page<span>; </span><span><a href="mzscheme.html#node_toc_start">contents</a></span><span><span>; </span><a href="mzscheme-Z-H-22.html#node_index_start">index</a></span>]</i></div>
<p></p>
<a name="node_chap_11"></a>
<h1 class=chapter>
<div class=chapterheading><a href="mzscheme.html#node_toc_node_chap_11">Chapter 11</a></div><br>
<a href="mzscheme.html#node_toc_node_chap_11">Input and Output</a></h1>
<p><a name="node_idx_1840"></a></p>
<p>
</p>
<a name="node_sec_11.1"></a>
<h2><a href="mzscheme.html#node_toc_node_sec_11.1">11.1 Ports</a></h2>
<p><a name="node_idx_1842"></a></p>
<p>
<a name="node_idx_1844"></a>
By definition, ports in MzScheme produce and consume bytes. When a
port is provided to a character-based operation, such as
<code class=scheme>read</code>, the port's bytes are read and interpreted as a UTF-8
encoding of characters (see also section <a href="mzscheme-Z-H-1.html#node_sec_1.2.3">1.2.3</a>). Thus, reading a
single character may require reading multiple bytes, and a procedure
like <code class=scheme>char-ready?</code> may need to peek several bytes into the
stream to determine whether a character is available. In the case of
a byte stream that does not correspond to a valid UTF-8 encoding,
functions such as <code class=scheme>read-char</code> may need to peek one byte ahead
in the stream to discover that the stream is not a valid encoding.</p>
<p>
When an input port produces a sequence of bytes that is not a valid
UTF-8 encoding in a character-reading context, then bytes that
constitute an invalid sequence are converted to the character
``?''. Specifically, bytes 255 and 254 are always converted to ``?'',
bytes in the range 192 to 253 produce ``?'' when they are not
followed by bytes that form a valid UTF-8 encoding, and bytes in the
range 128 to 191 are converted to ``?'' when they are not part of a
valid encoding that was started by a preceding byte in the range 192
to 253. To put it another way, when reading a sequence of bytes as
characters, a minimal set of bytes are changed to 63<a name="node_call_footnote_27"></a><a href="#node_footnote_27"><sup><small>27</small></sup></a> so that the entire
sequence of bytes is a valid UTF-8 encoding.</p>
<p>
See section <a href="mzscheme-Z-H-3.html#node_sec_3.6">3.6</a> for procedures that facilitate conversions
using UTF-8 or other encodings. See also
<code class=scheme>reencode-input-port</code> and <code class=scheme>reencode-output-port</code>
in Chapter <a href="../mzlib/mzlib-Z-H-32.html#node_chap_32">32</a>
in <a href="../mzlib/mzlib.html"><i>PLT MzLib: Libraries Manual</i></a> for obtaining a UTF-8-based port from one
that uses a different encoding of characters.</p>
<p>
<a name="node_idx_1846"></a><a name="node_kw_definitionport_Q_"></a><code class=scheme>(port?</code><tt> </tt><code class=scheme><span class=variable>v</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if either
<code class=scheme>(<code class=scheme>input-port?</code> <span class=variable>v</span>)</code> or <code class=scheme>(<code class=scheme>output-port?</code> <span class=variable>v</span>)</code> is <code class=scheme><span class=selfeval>#t</span></code>,
<code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
<a name="node_idx_1848"></a><a name="node_kw_definitionfile-stream-port_Q_"></a><code class=scheme>(file-stream-port?</code><tt> </tt><code class=scheme><span class=variable>port</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if the given port is
a file-stream port (see section <a href="#node_sec_11.1.6">11.1.6</a>, <code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
<a name="node_idx_1850"></a><a name="node_kw_definitionterminal-port_Q_"></a><code class=scheme>(terminal-port?</code><tt> </tt><code class=scheme><span class=variable>port</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if the given port is
attached to an interactive terminal, <code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
</p>
<a name="node_sec_11.1.1"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.1.1">11.1.1 End-of-File Constant</a></h3>
<p>The global variable <a name="node_idx_1852"></a><code class=scheme>eof</code> is bound to the end-of-file
value. The standard Scheme predicate <a name="node_idx_1854"></a><code class=scheme>eof-object?</code> returns
<code class=scheme><span class=selfeval>#t</span></code> only when applied to this value.</p>
<p>
Reading from a port produces an end-of-file result when the port has
no more data, but some ports may also return end-of-file
mid-stream. For example, a port connected to a Unix terminal returns
an end-of-file when the user types control-d; if the user provides
more input, the port returns additional bytes after the end-of-file.</p>
<p>
</p>
<a name="node_sec_11.1.2"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.1.2">11.1.2 Current Ports</a></h3>
<p>The standard Scheme procedures <a name="node_idx_1856"></a><code class=scheme>current-input-port</code> and
<a name="node_idx_1858"></a><code class=scheme>current-output-port</code> are implemented as parameters in
MzScheme. See section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.2">7.9.1.2</a> for more information.</p>
<p>
</p>
<a name="node_sec_11.1.3"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.1.3">11.1.3 Opening File Ports</a></h3>
<p></p>
<p>
The <a name="node_idx_1860"></a><code class=scheme>open-input-file</code> and <a name="node_idx_1862"></a><code class=scheme>open-output-file</code>
procedures accept an optional flag argument after the filename that
specifies a mode for the file:
</p>
<ul><p>
</p>
<li><p><code class=scheme><span class=selfeval>'binary</span></code><a name="node_idx_1864"></a> -- bytes are returned from the port
exactly as they are read from the file. Binary mode is the default
mode.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'text</span></code><a name="node_idx_1866"></a> -- return and linefeed bytes (10 and 13)
are written to and read from the file are filtered by the port in a
platform specific manner:
</p>
<ul><p>
</p>
<li><p><strong>Unix and Mac OS X</strong>: no filtering occurs.</p>
<p>
</p>
<li><p><strong>Windows reading</strong>: a return-linefeed combination from a
file is returned by the port as a single linefeed; no filtering
occurs for return bytes that are not followed by a linefeed, or for
a linefeed that is not preceded by a return.</p>
<p>
</p>
<li><p><strong>Windows writing</strong>: a linefeed written to the port is
translated into a return-linefeed combination in the file; no
filtering occurs for returns.</p>
<p>
</p>
</ul><p>
In Windows, <code class=scheme><span class=selfeval>'text</span></code> mode works only with regular files;
attempting to use <code class=scheme><span class=selfeval>'text</span></code> with other kinds of files triggers an
<a name="node_idx_1868"></a><code class=scheme>exn:fail:filesystem</code> exception.</p>
<p>
</p>
</ul><p></p>
<p>
The <a name="node_idx_1870"></a><code class=scheme>open-output-file</code> procedure can also take a flag
argument that specifies how to proceed when a file with the specified
name already exists:
</p>
<ul> <li><p><code class=scheme><span class=selfeval>'error</span></code><a name="node_idx_1872"></a> -- raise <a name="node_idx_1874"></a><code class=scheme>exn:fail:filesystem</code> (this is the default)
</p>
<li><p><code class=scheme><span class=selfeval>'replace</span></code><a name="node_idx_1876"></a> -- remove the old file and write a new one
</p>
<li><p><code class=scheme><span class=selfeval>'truncate</span></code><a name="node_idx_1878"></a> -- overwrite the old data
</p>
<li><p><code class=scheme><span class=selfeval>'truncate/replace</span></code><a name="node_idx_1880"></a> -- try <code class=scheme><span class=selfeval>'truncate</span></code>; if it fails,
try <code class=scheme><span class=selfeval>'replace</span></code>
</p>
<li><p><code class=scheme><span class=selfeval>'append</span></code><a name="node_idx_1882"></a> -- append to the end of the file under Unix and Mac OS X;
under Windows, <code class=scheme><span class=selfeval>'append</span></code> is equivalent to <code class=scheme><span class=selfeval>'update</span></code>, except that
the file position is immediately set to the end of the file after opening it
</p>
<li><p><code class=scheme><span class=selfeval>'update</span></code><a name="node_idx_1884"></a> -- open an existing file without truncating it;
if the file does not exist, the <a name="node_idx_1886"></a><code class=scheme>exn:fail:filesystem</code> exception is raised
</p>
</ul><p>
The <a name="node_idx_1888"></a><code class=scheme>open-input-output-file</code> procedure takes the same
arguments as <code class=scheme><code class=scheme>open-output-file</code></code>, but it produces two values:
an input port and an output port. The two ports are connected in that
they share the underlying file device. This procedure is intended for
use with special devices that can be opened by only one process, such
as <tt><strong>COM1</strong></tt> in Windows. For regular files, sharing the device can
be confusing. For example, using one port does not automatically
flush the other port's buffer (see section <a href="#node_sec_11.1.6">11.1.6</a> for more
information about buffers), and reading or writing in one port moves
the file position (if any) for the other port. For regular files, use
separate <code class=scheme>open-input-file</code> and <code class=scheme>open-output-file</code> calls
to avoid confusion.</p>
<p>
Extra flag arguments are passed to <code class=scheme><code class=scheme>open-output-file</code></code> in any
order. Appropriate flag arguments can also be passed as the last
argument(s) to <a name="node_idx_1890"></a><code class=scheme>call-with-input-file</code>,
<a name="node_idx_1892"></a><code class=scheme>with-input-from-file</code>, <a name="node_idx_1894"></a><code class=scheme>call-with-output-file</code>,
and <a name="node_idx_1896"></a><code class=scheme>with-output-to-file</code>. When conflicting flag arguments
(e.g., both <code class=scheme><span class=selfeval>'error</span></code> and <code class=scheme><span class=selfeval>'replace</span></code>) are provided to
<code class=scheme><code class=scheme>open-output-file</code></code>, <a name="node_idx_1898"></a><code class=scheme>with-output-to-file</code>, or
<a name="node_idx_1900"></a><code class=scheme>call-with-output-file</code>, the
<a name="node_idx_1902"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
Both <a name="node_idx_1904"></a><code class=scheme>with-input-from-file</code> and
<a name="node_idx_1906"></a><code class=scheme>with-output-to-file</code> close the port they create if control
jumps out of the supplied thunk (either through a continuation or an
exception), and the port remains closed if control jumps back into
the thunk. The current input or output port is installed and restored
with <code class=scheme><span class=keyword>parameterize</span></code> (see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.2">7.9.2</a>).</p>
<p>
See section <a href="#node_sec_11.1.6">11.1.6</a> for more information on file ports. When an
input or output file-stream port is created, it is placed into the
management of the current custodian (see section <a href="mzscheme-Z-H-9.html#node_sec_9.2">9.2</a>).</p>
<p>
</p>
<a name="node_sec_11.1.4"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.1.4">11.1.4 Pipes</a></h3>
<p></p>
<p>
<a name="node_idx_1908"></a><a name="node_kw_definitionmake-pipe"></a><code class=scheme>(make-pipe</code><tt> </tt>[<code class=scheme><span class=variable>limit-k input-name-v output-name-v</span></code>]<code class=scheme>)</code> returns two port
values (see section <a href="mzscheme-Z-H-2.html#node_sec_2.2">2.2</a>): the first port is an input port and the
second is an output port. Data written to the output port is read
from the input port. The ports do not need to be explicitly closed.</p>
<p>
The optional <code class=scheme><span class=variable>limit-k</span></code> argument can be <code class=scheme><span class=selfeval>#f</span></code> or a positive
exact integer. If <code class=scheme><span class=variable>limit-k</span></code> is omitted or <code class=scheme><span class=selfeval>#f</span></code>, the new
pipe holds an unlimited number of unread bytes (i.e., limited only by
the available memory). If <code class=scheme><span class=variable>limit-k</span></code> is a positive number, then
the pipe will hold at most <code class=scheme><span class=variable>limit-k</span></code> unread/unpeeked bytes;
writing to the pipe's output port thereafter will block until a read
or peek from the input port makes more space available. (Peeks
effectively extend the port's capacity until the peeked bytes are
read.)</p>
<p>
The optional <code class=scheme><span class=variable>input-name-v</span></code> and <code class=scheme><span class=variable>output-name-v</span></code> are used as
the names for the returned input and out ports, respectively, if they
are supplied. Otherwise, the name of each port is <code class=scheme><span class=selfeval>'pipe</span></code>.</p>
<p>
<a name="node_idx_1910"></a><a name="node_kw_definitionpipe-content-length"></a><code class=scheme>(pipe-content-length</code><tt> </tt><code class=scheme><span class=variable>pipe-port</span></code><code class=scheme>)</code> returns the number of bytes
contained in a pipe, where <code class=scheme><span class=variable>pipe-port</span></code> is either of the pipe's
ports produced by <code class=scheme>make-pipe</code>. The pipe's content length
counts all bytes that have been written to the pipe and not yet read
(though possibly peeked).</p>
<p>
</p>
<a name="node_sec_11.1.5"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.1.5">11.1.5 String Ports</a></h3>
<p></p>
<p>
<a name="node_idx_1912"></a>
<a name="node_idx_1914"></a>
<a name="node_idx_1916"></a>
<a name="node_idx_1918"></a>
<a name="node_idx_1920"></a>
<a name="node_idx_1922"></a>
Scheme input and output can be read from or collected into a string or
byte string:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_1924"></a><a name="node_kw_definitionopen-input-bytes"></a><code class=scheme>(open-input-bytes</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>name-v</span></code>]<code class=scheme>)</code> creates an input port
that reads characters from <code class=scheme><span class=variable>bytes</span></code> (see
section <a href="mzscheme-Z-H-3.html#node_sec_3.6">3.6</a>). Modifying <code class=scheme><span class=variable>bytes</span></code> afterward does not
affect the byte stream produced by the port. The optional
<code class=scheme><span class=variable>name-v</span></code> argument is used as the name for the returned port; the
default is <code class=scheme><span class=selfeval>'string</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_1926"></a><a name="node_kw_definitionopen-input-string"></a><code class=scheme>(open-input-string</code><tt> </tt><code class=scheme><span class=variable>string</span></code><tt> </tt>[<code class=scheme><span class=variable>name-v</span></code>]<code class=scheme>)</code> creates an input port
that reads bytes from the UTF-8 encoding (see section <a href="mzscheme-Z-H-1.html#node_sec_1.2.3">1.2.3</a>) of
<code class=scheme><span class=variable>string</span></code>. The optional <code class=scheme><span class=variable>name-v</span></code> argument is used as the name
for the returned port; the default is <code class=scheme><span class=selfeval>'string</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_1928"></a><a name="node_kw_definitionopen-output-bytes"></a><code class=scheme>(open-output-bytes</code><tt> </tt>[<code class=scheme><span class=variable>name-v</span></code>]<code class=scheme>)</code> creates an output port that
accumulates the output into a byte string. The optional <code class=scheme><span class=variable>name-v</span></code>
argument is used as the name for the returned port; the default is
<code class=scheme><span class=selfeval>'string</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_1930"></a><a name="node_kw_definitionopen-output-string"></a><code class=scheme>(open-output-string</code><tt> </tt>[<code class=scheme><span class=variable>name-v</span></code>]<code class=scheme>)</code> creates an output port that
accumulates the output into a byte string. This procedure is the
same as <code class=scheme>open-output-bytes</code>.</p>
<p>
</p>
<li><p><a name="node_idx_1932"></a><a name="node_kw_definitionget-output-bytes"></a><code class=scheme>(get-output-bytes</code><tt> </tt><code class=scheme><span class=variable>string-output-port</span></code><code class=scheme>)</code> returns the
bytes accumulated in <code class=scheme><span class=variable>string-output-port</span></code> so far in a
freshly-allocated byte string. The bytes also remain in the port for
further accumulation or for later calls to
<code class=scheme>get-output-bytes</code> or <code class=scheme>get-output-string</code>.</p>
<p>
</p>
<li><p><a name="node_idx_1934"></a><a name="node_kw_definitionget-output-string"></a><code class=scheme>(get-output-string</code><tt> </tt><code class=scheme><span class=variable>string-output-port</span></code><code class=scheme>)</code> returns
<code class=scheme>(<code class=scheme>bytes->string/utf-8</code> (<code class=scheme>get-output-bytes</code> <span class=variable>string-output-port</span>) <span class=selfeval>#\?</span>)</code>;
see also section <a href="mzscheme-Z-H-3.html#node_sec_3.6">3.6</a>.</p>
<p>
</p>
</ul><p></p>
<p>
String input and output ports do not need to be explicitly closed. The
<code class=scheme><code class=scheme>file-position</code></code> procedure, described in section <a href="#node_sec_11.1.6">11.1.6</a>,
works for string ports in position-setting mode.</p>
<p>
Example:
</p>
<div align=left><pre class=scheme>(<span class=keyword>define</span> <span class=variable>i</span> (<code class=scheme>open-input-string</code> <span class=selfeval>"hello world"</span>))
(<span class=keyword>define</span> <span class=variable>o</span> (<code class=scheme>open-output-string</code>))
(<code class=scheme>write</code> (<code class=scheme>read</code> <span class=variable>i</span>) <span class=variable>o</span>)
(<code class=scheme>get-output-string</code> <span class=variable>o</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"hello"</span></code></span>
</pre></div><p></p>
<p>
</p>
<a name="node_sec_11.1.6"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.1.6">11.1.6 File-Stream Ports</a></h3>
<p></p>
<p>
<a name="node_idx_1936"></a>
<a name="node_idx_1938"></a>
A port created by <code class=scheme><code class=scheme>open-input-file</code></code>, <code class=scheme><code class=scheme>open-output-file</code></code>,
<code class=scheme><code class=scheme>subprocess</code></code>, and related functions is a <strong>file-stream
port</strong>. The initial input, output, and error ports in stand-alone
MzScheme are also file-stream ports. The <code class=scheme>file-stream-port?</code>
predicate recognizes file-stream ports.</p>
<p>
An input port is block buffered by default, which means that on any
read, the buffer is filled with immediately-available bytes to speed
up future reads. Thus, if a file is modified between a pair of reads
to the file, the second read can produce stale data. Calling
<code class=scheme><code class=scheme>file-position</code></code> to set an input port's file position flushes
its buffer.</p>
<p>
Most output ports are block buffered by default, but a terminal output
port is line buffered, and the error output port is unbuffered. An
output buffer is filled with a sequence of written bytes to be
committed as a group, either when the buffer is full (in block mode)
or when a newline is written (in line mode).</p>
<p>
A port's buffering can be changed via <code class=scheme><code class=scheme>file-stream-buffer-mode</code></code>
(described below). The two ports produced by
<code class=scheme>open-input-output-file</code> have independent buffers.</p>
<p>
The following procedures work primarily on file-stream ports:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_1940"></a><a name="node_kw_definitionflush-output"></a><code class=scheme>(flush-output</code><tt> </tt>[<code class=scheme><span class=variable>output-port</span></code>]<code class=scheme>)</code> <a name="node_idx_1942"></a> forces
all buffered data in the given output port to be physically
written. If <code class=scheme><span class=variable>output-port</span></code> is omitted, then the current output
port is flushed. Only file-stream ports and custom ports (see
section <a href="#node_sec_11.1.7">11.1.7</a>) use buffers; when called on a port without a
buffer, <code class=scheme><code class=scheme>flush-output</code></code> has no effect.</p>
<p>
By default, a file-stream port is block-buffered, but this behavior
can be modified with <code class=scheme>file-stream-buffer-mode</code>. In addition,
the initial current output and error ports are automatically flushed
when <code class=scheme><code class=scheme>read</code></code><a name="node_call_footnote_28"></a><a href="#node_footnote_28"><sup><small>28</small></sup></a>, <code class=scheme><code class=scheme>read-line</code></code>, <code class=scheme><code class=scheme>read-bytes</code></code>,
<code class=scheme><code class=scheme>read-string</code></code>, etc. are performed on the initial standard
input port.</p>
<p>
</p>
<li><p><a name="node_idx_1944"></a><a name="node_kw_definitionfile-stream-buffer-mode"></a><code class=scheme>(file-stream-buffer-mode</code><tt> </tt><code class=scheme><span class=variable>port</span></code><tt> </tt>[<code class=scheme><span class=variable>mode-symbol</span></code>]<code class=scheme>)</code> gets or sets
the buffer mode for <code class=scheme><span class=variable>port</span></code>, if possible. All file-stream ports
support setting the buffer mode, TCP ports (see section <a href="#node_sec_11.4">11.4</a>)
support setting and getting the buffer mode, and custom ports (see
section <a href="#node_sec_11.1.7">11.1.7</a>) may support getting and setting buffer modes.</p>
<p>
If <code class=scheme><span class=variable>mode-symbol</span></code> is provided, it must be one of
<code class=scheme><span class=selfeval>'none</span></code><a name="node_idx_1946"></a>, <code class=scheme><span class=selfeval>'line</span></code><a name="node_idx_1948"></a> (output only), or
<code class=scheme><span class=selfeval>'block</span></code><a name="node_idx_1950"></a>, and the port's buffering is set accordingly. If
the port does not support setting the mode, the <a name="node_idx_1952"></a><code class=scheme>exn:fail</code> exception is raised.</p>
<p>
If <code class=scheme><span class=variable>mode-symbol</span></code> is not provided, the current mode is returned,
or <code class=scheme><span class=selfeval>#f</span></code> is returned if the mode cannot be determined. If
<code class=scheme><span class=variable>file-stream-port</span></code> is an input port and <code class=scheme><span class=variable>mode-symbol</span></code> is
<code class=scheme><span class=selfeval>'line</span></code>, the <a name="node_idx_1954"></a><code class=scheme>exn:fail:contract</code> exception is raised. </p>
<p>
For an input port, peeking always places peeked bytes into the port's
buffer, even when the port's buffer mode is <code class=scheme><span class=selfeval>'none</span></code>;
furthermore, on some platforms, testing the port for input (via
<code class=scheme><code class=scheme>char-ready?</code></code> or <code class=scheme>sync</code>) may be implemented with a
peek. If an input port's buffer mode is <code class=scheme><span class=selfeval>'none</span></code>, then at most
one byte is read for <code class=scheme><code class=scheme>read-bytes-avail!*</code></code>,
<code class=scheme><code class=scheme>read-bytes-avail!</code></code>, <code class=scheme><code class=scheme>peek-bytes-avail!*</code></code>, or
<code class=scheme><code class=scheme>peek-bytes-avail!</code></code>; if any bytes are buffered in the port
(e.g., to satisfy a previous peek), the procedures may access
multiple buffered bytes, but no further bytes are read.</p>
<p>
</p>
<li><p><a name="node_idx_1956"></a><a name="node_kw_definitionfile-position"></a><code class=scheme>(file-position</code><tt> </tt><code class=scheme><span class=variable>port</span></code><code class=scheme>)</code> returns the current read/write
position of <code class=scheme><span class=variable>port</span></code>. For file-stream and string
ports, <a name="node_idx_1958"></a><a name="node_kw_definitionfile-position/set"></a><code class=scheme>(file-position</code><tt> </tt><code class=scheme><span class=variable>port k-or-eof</span></code><code class=scheme>)</code> sets the read/write
position to <code class=scheme><span class=variable>k-or-eof</span></code> relative to the beginning of the
file/string if <code class=scheme><span class=variable>k-or-eof</span></code> is a number, or to the current end of
the file/string if <code class=scheme><span class=variable>k-or-eof</span></code> is <code class=scheme>eof</code>. In
position-setting mode, <code class=scheme>file-position</code> raises
the <a name="node_idx_1960"></a><code class=scheme>exn:fail:contract</code> exception for port kinds other than
file-stream and string ports. Calling <code class=scheme><code class=scheme>file-position</code></code> without
a position on a non-file/non-string input port returns the number of
bytes that have been read from that port if the position is known
(see section <a href="#node_sec_11.2.1.1">11.2.1.1</a>), otherwise the <a name="node_idx_1962"></a><code class=scheme>exn:fail:filesystem</code> exception is raised.</p>
<p>
When <code class=scheme>(file-position <code class=scheme><span class=variable>port</span></code> <code class=scheme><span class=variable>k</span></code>)</code> sets the position
<code class=scheme><span class=variable>k</span></code> beyond the current size of an output file or string, the
file/string is enlarged to size <code class=scheme><span class=variable>k</span></code> and the new region is filled
with <code class=scheme><span class=selfeval>#\nul</span></code>. If <code class=scheme><span class=variable>k</span></code> is beyond the end of an input file or
string, then reading thereafter returns <code class=scheme><code class=scheme>eof</code></code> without changing
the port's position.</p>
<p>
Not all file-stream ports support setting the position. If
<code class=scheme><code class=scheme>file-position</code></code> is called with a position argument on such a
file-stream port, the <a name="node_idx_1964"></a><code class=scheme>exn:fail:filesystem</code> exception is raised.</p>
<p>
When changing the file position for an output port, the port is first
flushed if its buffer is not empty. Similarly, setting the position
for an input port clears the port's buffer (even if the new position
is the same as the old position). However, although input and output
ports produced by <code class=scheme><span class=variable>open-input-output-file</span></code> share the file
position, setting the position via one port does not flush the other
port's buffer.</p>
<p>
</p>
<li><p><a name="node_idx_1966"></a><a name="node_kw_definitionport-file-identity"></a><code class=scheme>(port-file-identity</code><tt> </tt><code class=scheme><span class=variable>file-stream-port</span></code><code class=scheme>)</code> <a name="node_idx_1968"></a> returns
an exact positive integer that represents the identity of the device
and file read or written by <code class=scheme><span class=variable>file-stream-port</span></code>. For two ports
whose open times overlap, the result of <code class=scheme>port-file-identity</code>
is the same for both ports if and only if the ports access the same
device and file. For ports whose open times do not overlap, no
guarantee is provided for the port identities (even if the ports
actually access the same file) -- except as can be inferred through
relationships with other ports. If <code class=scheme><span class=variable>file-stream-port</span></code> is closed,
the <a name="node_idx_1970"></a><code class=scheme>exn:fail</code> exception is raised. Under Windows 95, 98, and Me, if
<code class=scheme><span class=variable>file-stream-port</span></code> is connected to a pipe instead of a file, the
<a name="node_idx_1972"></a><code class=scheme>exn:fail:filesystem</code> exception is raised.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.1.7"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.1.7">11.1.7 Custom Ports</a></h3>
<p></p>
<p>
<a name="node_idx_1974"></a>
The <code class=scheme><code class=scheme>make-input-port</code></code> and <code class=scheme><code class=scheme>make-output-port</code></code> procedures
create custom ports with arbitrary control procedures. Correctly
implementing a custom port can be tricky, because it amounts to
implementing a device driver. Custom ports are mainly useful to
obtain fine control over the action of committing bytes as read or
written.</p>
<p>
Many simple port variations can be implemented using threads and
pipes. For example, if <code class=scheme><span class=variable>get-next-char</span></code> is a function that
produces either a character or <code class=scheme><code class=scheme>eof</code></code>, it can be turned into an
input port as follows
</p>
<div align=left><pre class=scheme>(<span class=keyword>let-values</span> ([(<span class=variable>r</span> <span class=variable>w</span>) (<code class=scheme>make-pipe</code> <span class=selfeval>4096</span>)])
<span class=comment>;; Create a thread to move chars from <code class=scheme><span class=variable>get-next-char</span></code> to the pipe</span>
(<code class=scheme>thread</code> (<span class=keyword>lambda</span> () (<span class=keyword>let</span> <span class=variable>loop</span> ()
(<span class=keyword>let</span> ([<span class=variable>v</span> (<span class=variable>get-next-char</span>)])
(<span class=keyword>if</span> (<span class=variable>eof-object?</span> <span class=variable>v</span>)
(<code class=scheme>close-output-port</code> <span class=variable>w</span>)
(<span class=keyword>begin</span>
(<code class=scheme>write-char</code> <span class=variable>v</span> <span class=variable>w</span>)
(<span class=variable>loop</span>)))))))
<span class=comment>;; Return the read end of the pipe</span>
<span class=variable>r</span>)
</pre></div><p>
The <tt><strong>port.ss</strong></tt> in MzLib provides several other port constructors; see
Chapter <a href="../mzlib/mzlib-Z-H-32.html#node_chap_32">32</a>
in <a href="../mzlib/mzlib.html"><i>PLT MzLib: Libraries Manual</i></a>.</p>
<p>
</p>
<a name="node_sec_11.1.7.1"></a>
<h4><a href="mzscheme.html#node_toc_node_sec_11.1.7.1">11.1.7.1 Custom Input</a></h4>
<p></p>
<p>
<a name="node_idx_1976"></a><a name="node_kw_definitionmake-input-port"></a><code class=scheme>(make-input-port</code><tt> </tt><code class=scheme><span class=variable>name-v read-proc optional-peek-proc close-proc</span></code><tt> </tt>[<code class=scheme><span class=variable>optional-progress-evt-proc optional-commit-proc optional-location-proc count-lines!-proc init-position optional-buffer-mode-proc</span></code>]<code class=scheme>)</code>
creates an input port. The port is immediately open for reading. If
<code class=scheme><span class=variable>close-proc</span></code> procedure has no side effects, then the port need
not be explicitly closed.</p>
<p>
</p>
<ul><p>
</p>
<li><p><code class=scheme><span class=variable>name-v</span></code> -- the name for the input port, which is
reported by <code class=scheme>object-name</code> (see section <a href="mzscheme-Z-H-6.html#node_sec_6.2.4">6.2.4</a>).</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>read-proc</span></code> -- a procedure that takes a single argument:
a mutable byte string to receive read bytes. The procedure's
result is one of the following:
</p>
<ul><p>
</p>
<li><p>the number of bytes read, as an exact, non-negative integer;</p>
<p>
</p>
<li><p><code class=scheme><code class=scheme>eof</code></code>;</p>
<p>
</p>
<li><p>a procedure of arity four (representing a ``special''
result, as discussed further below) and optionally of arity two,
but a procedure result is allowed only when
<code class=scheme><span class=variable>optional-peek-proc</span></code> is not <code class=scheme><span class=selfeval>#f</span></code>; or</p>
<p>
</p>
<li><p>a synchronizable event (see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>) that becomes
ready when the read is complete (roughly): the event's value can
one of the above three results or another event like itself; in
the last case, a reading process loops with <code class=scheme><code class=scheme>sync</code></code> until
it gets a non-event result.</p>
<p>
</p>
</ul><p>
The <code class=scheme><span class=variable>read-proc</span></code> procedure must not block indefinitely. If no
bytes are immediately available for reading, the <code class=scheme><span class=variable>read-proc</span></code>
must return <code class=scheme><span class=selfeval>0</span></code> or an event, and preferably an event (to
avoid busy waits). The <code class=scheme><span class=variable>read-proc</span></code> should not return
<code class=scheme><span class=selfeval>0</span></code> (or an event whose value is <code class=scheme><span class=selfeval>0</span></code>) when data is
available in the port, otherwise polling the port will behave
incorrectly. An event result from an event can also break polling.</p>
<p>
If the result of a <code class=scheme><span class=variable>read-proc</span></code> call is not one of the above
values, the <a name="node_idx_1978"></a><code class=scheme>exn:fail:contract</code> exception is raised. If a returned integer is
larger than the supplied byte string's length, the
<a name="node_idx_1980"></a><code class=scheme>exn:fail:contract</code> exception is raised. If <code class=scheme><span class=variable>optional-peek-proc</span></code> is
<code class=scheme><span class=selfeval>#f</span></code> and a procedure for a special result is returned, the
<a name="node_idx_1982"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
The <code class=scheme><span class=variable>read-proc</span></code> procedure can report an error by raising an
exception, but only if no bytes are read. Similarly, no bytes
should be read if <code class=scheme><code class=scheme>eof</code></code>, an event, or a procedure is
returned. In other words, no bytes should be lost due to spurious
exceptions or non-byte data.</p>
<p>
A port's reading procedure may be called in multiple threads
simultaneously (if the port is accessible in multiple threads),
and the port is responsible for its own internal
synchronization. Note that improper implementation of such
synchronization mechanisms might cause a non-blocking read
procedure to block indefinitely.</p>
<p>
If <code class=scheme><span class=variable>optional-peek-proc</span></code>, <code class=scheme><span class=variable>optional-progress-evt-proc</span></code>, and
<code class=scheme><span class=variable>optional-commit-proc</span></code> are all provided and
non-<code class=scheme><span class=selfeval>#f</span></code>, then the following is an acceptable implementation
of <code class=scheme><span class=variable>read-proc</span></code>:
</p>
<div align=left><pre class=scheme> (<span class=keyword>lambda</span> (<span class=variable>bstr</span>)
(<span class=keyword>let*</span> ([<span class=variable>progress-evt</span> (<span class=variable>progress-evt-proc</span>)]
[<span class=variable>v</span> (<span class=variable>peek-proc</span> <span class=variable>bstr</span> <span class=selfeval>0</span> <span class=variable>progress-evt</span>)])
(<span class=keyword>cond</span>
[(<code class=scheme>sync/timeout</code> <span class=selfeval>0</span> <span class=variable>progress-evt</span>) <span class=selfeval>0</span>] <span class=comment>; try again</span>
[(<code class=scheme>evt?</code> <span class=variable>v</span>) (<span class=variable>wrap-evt</span> <span class=variable>v</span> (<span class=keyword>lambda</span> (<span class=variable>x</span>) <span class=selfeval>0</span>))] <span class=comment>; sync, then try again</span>
[(<span class=keyword>and</span> (<code class=scheme>number?</code> <span class=variable>v</span>) (<code class=scheme>zero?</code> <span class=variable>v</span>)) <span class=selfeval>0</span>] <span class=comment>; try again</span>
[<span class=keyword>else</span>
(<span class=keyword>if</span> (<span class=variable>optional-commit-proc</span> (<span class=keyword>if</span> (<code class=scheme>number?</code> <span class=variable>v</span>) <span class=variable>v</span> <span class=selfeval>1</span>)
<span class=variable>progress-evt</span>
<span class=variable>always-evt</span>)
<span class=variable>v</span> <span class=comment>; got a result</span>
<span class=selfeval>0</span>)]))) <span class=comment>; try again</span>
</pre></div><p>
An implementor may choose not to implement the <code class=scheme><span class=variable>optional-</span></code>
procedures, however, and even an implementor who does supply
<code class=scheme><span class=variable>optional-</span></code> procedures may provide a different <code class=scheme><span class=variable>read-proc</span></code>
that uses a fast path for non-blocking reads.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-peek-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> or a procedure
that takes three arguments:
</p>
<ul><p>
</p>
<li><p>a mutable byte string to receive peeked bytes;</p>
<p>
</p>
<li><p>a non-negative number of bytes (or specials) to skip before
peeking; and</p>
<p>
</p>
<li><p>either <code class=scheme><span class=selfeval>#f</span></code> or a progress event produced by
<code class=scheme><span class=variable>optional-progress-evt-proc</span></code>.</p>
<p>
</p>
</ul><p>
The results and conventions for <code class=scheme><span class=variable>optional-peek-proc</span></code> are
mostly the same as for <code class=scheme><span class=variable>read-proc</span></code>. The main difference is in
the handling of the progress event, if it is not <code class=scheme><span class=selfeval>#f</span></code>. If
the given progress event becomes ready, the
<code class=scheme><span class=variable>optional-peek-proc</span></code> must abort any skip attempts and not peek
any values. In particular, <code class=scheme><span class=variable>optional-peek-proc</span></code> must not peek
any values if the progress event is initially ready.</p>
<p>
Unlike <code class=scheme><span class=variable>read-proc</span></code>, <code class=scheme><span class=variable>optional-peek-proc</span></code> should produce
<code class=scheme><span class=selfeval>#f</span></code> (or an event whose value is <code class=scheme><span class=selfeval>#f</span></code>) if no bytes
were peeked because the progress event became ready. Like
<code class=scheme><span class=variable>read-proc</span></code>, a <code class=scheme><span class=selfeval>0</span></code> result indicates that another
attempt is likely to succeed, so <code class=scheme><span class=selfeval>0</span></code> is inappropriate when
the progress event is ready. Also like <code class=scheme><span class=variable>read-proc</span></code>,
<code class=scheme><span class=variable>optional-peek-proc</span></code> must not block indefinitely.</p>
<p>
The skip count provided to <code class=scheme><span class=variable>optional-peek-proc</span></code> is a number of
bytes (or specials) that must remain present in the port -- in
addition to the peek results -- when the peek results are
reported. If a progress event is supplied, then the peek is
effectively canceled when another process reads data before the
given number can be skipped. If a progress event is not supplied
and data is read, then the peek must effectively restart with the
original skip count.</p>
<p>
The system does not check that multiple peeks return consistent
results, or that peeking and reading produce consistent results.</p>
<p>
If <code class=scheme><span class=variable>optional-peek-proc</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then peeking for the
port is implemented automatically in terms of reads, but with
several limitations. First, the automatic implementation is not
thread-safe. Second, the automatic implementation cannot handle
special results (non-byte and non-eof), so <code class=scheme><span class=variable>read-proc</span></code> cannot
return a procedure for a special when <code class=scheme><span class=variable>optional-peek-proc</span></code> is
<code class=scheme><span class=selfeval>#f</span></code>. Finally, the automatic peek implementation is
incompatible with progress events, so if <code class=scheme><span class=variable>optional-peek-proc</span></code>
is <code class=scheme><span class=selfeval>#f</span></code>, then <code class=scheme><span class=variable>progress-evt-proc</span></code> and
<code class=scheme><span class=variable>optional-commit-proc</span></code> must be <code class=scheme><span class=selfeval>#f</span></code>. See also
<code class=scheme>make-input-port/peek-to-read</code> in Chapter <a href="../mzlib/mzlib-Z-H-32.html#node_chap_32">32</a>
in <a href="../mzlib/mzlib.html"><i>PLT MzLib: Libraries Manual</i></a>.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>close-proc</span></code> -- a procedure of zero arguments that is
called to close the port. The port is not considered closed until
the closing procedure returns. The port's procedures will never be
used again via the port after it is closed. However, the closing
procedure can be called simultaneously in multiple threads (if the
port is accessible in multiple threads), and it may be called
during a call to the other procedures in another thread; in the
latter case, any outstanding reads and peeks should be terminated
with an error.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-progress-evt-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> (the
default), or a procedure that takes no arguments and returns an
event. The event must become ready only after data is next read
from the port or the port is closed. After the event becomes
ready, it must remain so. (See also <code class=scheme>semaphore-peek-evt</code> in
section <a href="mzscheme-Z-H-7.html#node_sec_7.4">7.4</a>.)</p>
<p>
If <code class=scheme><span class=variable>optional-progress-evt-proc</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then
<code class=scheme>port-provides-progress-evts?</code> applied to the port will
produce <code class=scheme><span class=selfeval>#f</span></code>, and the port will not be a valid argument to
<code class=scheme>port-progress-evt</code>.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-commit-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> (the
default), or a procedure that takes three arguments:
</p>
<ul><p>
</p>
<li><p>an exact, positive integer <em>k</em><sub><em>r</em></sub>;</p>
<p>
</p>
<li><p>a progress event produced by <code class=scheme><span class=variable>optional-progress-evt-proc</span></code>;</p>
<p>
</p>
<li><p>an event, <code class=scheme><span class=variable>done-evt</span></code>, that is either a channel-put
event, channel, semaphore, semaphore-peek event, always
event, or never event.</p>
<p>
</p>
</ul><p>
A <strong>commit</strong> corresponds to removing data from the stream
that was previously peeked, but only if no other process removed
data first. (The removed data does not need to be reported,
because it has been peeked already.) More precisely, assuming
that <em>k</em><sub><em>p</em></sub> bytes, specials, and mid-stream <code class=scheme><code class=scheme>eof</code></code>s have
been previously peeked or skipped at the start of the port's
stream, <code class=scheme><span class=variable>optional-commit-proc</span></code> must satisfy the following
constraints:
</p>
<ul><p>
</p>
<li><p>It must return only when the commit is complete or when the
given progress event becomes ready.</p>
<p>
</p>
<li><p>It must commit only if <em>k</em><sub><em>p</em></sub> is positive.</p>
<p>
</p>
<li><p>If it commits, then it must do so with either <em>k</em><sub><em>r</em></sub> items
or <em>k</em><sub><em>p</em></sub> items, whichever is smaller, and only if <em>k</em><sub><em>p</em></sub> is
positive.</p>
<p>
</p>
<li><p>It must never choose <code class=scheme><span class=variable>done-evt</span></code> in a synchronization
after the given progress event is ready, or after <code class=scheme><span class=variable>done-evt</span></code>
has been synchronized once.</p>
<p>
</p>
<li><p>It must not treat any data as read from the port unless
<code class=scheme><span class=variable>done-evt</span></code> is chosen in a synchronization.</p>
<p>
</p>
<li><p>It must not block indefinitely if <code class=scheme><span class=variable>done-evt</span></code> is ready;
it must return soon after the read completes or soon after the
given progress event is ready, whichever is first.</p>
<p>
</p>
<li><p>It can report an error by raising an exception, but only if
no data is committed. In other words, no data should be lost due to
an exception, including a break exception.</p>
<p>
</p>
<li><p>It must return a true value if data is committed,
<code class=scheme><span class=selfeval>#f</span></code> otherwise. When it returns a value, the given
progress event must be ready (perhaps because data was just
committed).</p>
<p>
</p>
<li><p>It must raise an exception if no data (including
<code class=scheme><code class=scheme>eof</code></code>) has been peeked from the beginning of the port's
stream, or if it would have to block indefinitely to wait for the
given progress event to become ready.</p>
<p>
</p>
</ul><p>
A call to <code class=scheme><span class=variable>optional-commit-proc</span></code> is
<code class=scheme><span class=keyword>parameterize-break</span></code>ed to disable breaks.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-location-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> (the
default), or a procedure that takes no arguments and returns three
values: the line number for the next item in the port's stream (a
positive number or <code class=scheme><span class=selfeval>#f</span></code>), the column number for the next
item in the port's stream (a non-negative number or <code class=scheme><span class=selfeval>#f</span></code>),
and the position for the next item in the port's stream (a
positive number or <code class=scheme><span class=selfeval>#f</span></code>). See also section <a href="#node_sec_11.2.1.1">11.2.1.1</a>. </p>
<p>
This procedure is only called if line counting is enabled for the
port via <code class=scheme>port-count-lines!</code> (in which case
<code class=scheme><span class=variable>count-lines!-proc</span></code> is called). The <code class=scheme><code class=scheme>read</code></code>,
<code class=scheme><code class=scheme>read-syntax</code></code>, <code class=scheme>read-honu</code>, and
<code class=scheme>read-honu-syntax</code> procedures assume that reading a
non-whitespace character increments the column and position by
one.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>count-lines!-proc</span></code> -- a procedure of no arguments
that is called if and when line counting is enabled for the port.
The default procedure is <code class=scheme>void</code>.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>init-position</span></code> -- an exact, positive integer that
determines the position of the port's first item, used when line
counting is <em>not</em> enabled for the port. The default is
<code class=scheme><span class=selfeval>1</span></code>.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-buffer-mode-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> (the
default) or a procedure that accepts zero or one arguments. If
<code class=scheme><span class=variable>optional-buffer-mode-proc</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then the resulting
port does not support a buffer-mode setting. Otherwise, the
procedure is called with one symbol argument (<code class=scheme><span class=selfeval>'block</span></code> or
<code class=scheme><span class=selfeval>'none</span></code>) to set the buffer mode, and it is called with zero
arguments to get the current buffer mode. In the latter case, the
result must be <code class=scheme><span class=selfeval>'block</span></code>, <code class=scheme><span class=selfeval>'none</span></code>, or <code class=scheme><span class=selfeval>#f</span></code>
(unknown). See section <a href="#node_sec_11.1.6">11.1.6</a> for more information on buffer
modes.</p>
<p>
</p>
</ul><p></p>
<p>
When <code class=scheme><span class=variable>read-proc</span></code> or <code class=scheme><span class=variable>optional-peek-proc</span></code> (or an event
produced by one of these) returns a procedure, and the procedure is
used to obtain a non-byte result.<a name="node_call_footnote_29"></a><a href="#node_footnote_29"><sup><small>29</small></sup></a> The procedure is called by
<code class=scheme><code class=scheme>read</code></code>,<a name="node_call_footnote_30"></a><a href="#node_footnote_30"><sup><small>30</small></sup></a>
<code class=scheme><code class=scheme>read-syntax</code></code>, <code class=scheme>read-honu</code>, <code class=scheme>read-honu-syntax</code>,
<code class=scheme>read-byte-or-special</code>, <code class=scheme>read-char-or-special</code>,
<code class=scheme>peek-byte-or-special</code>, or <code class=scheme>peek-char-or-special</code>. The
special-value procedure can return an arbitrary value, and it will be
called zero or one times (not necessarily before further reads or
peeks from the port). See section <a href="#node_sec_11.2.9">11.2.9</a> for more details on
the procedure's arguments and result.</p>
<p>
If <code class=scheme><span class=variable>read-proc</span></code> or <code class=scheme><span class=variable>optional-peek-proc</span></code> returns a special
procedure when called by any reading procedure other than
<code class=scheme><code class=scheme>read</code></code>, <code class=scheme><code class=scheme>read-syntax</code></code>, <code class=scheme>read-honu</code>,
<code class=scheme>read-honu-syntax</code>, <code class=scheme><code class=scheme>read-char-or-special</code></code>,
<code class=scheme><code class=scheme>peek-char-or-special</code></code>, <code class=scheme><code class=scheme>read-byte-or-special</code></code>, or
<code class=scheme><code class=scheme>peek-byte-or-special</code></code>, then the <a name="node_idx_1984"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
Examples:
</p>
<div align=left><pre class=scheme><span class=comment>;; A port with no input...</span>
<span class=comment>;; Easy: <code class=scheme>(<code class=scheme>open-input-bytes</code> <span class=selfeval>#</span><span class=selfeval>""</span>)</code></span>
<span class=comment>;; Hard:</span>
(<span class=keyword>define</span> <span class=variable>/dev/null-in</span>
(<code class=scheme>make-input-port</code> <span class=keyword>'</span><code class=scheme>null</code>
(<span class=keyword>lambda</span> (<span class=variable>s</span>) <code class=scheme>eof</code>)
(<span class=keyword>lambda</span> (<span class=variable>skip</span> <span class=variable>s</span> <span class=variable>progress-evt</span>) <code class=scheme>eof</code>)
<code class=scheme>void</code>
(<span class=keyword>lambda</span> () <span class=variable>never-evt</span>)
(<span class=keyword>lambda</span> (<span class=variable>k</span> <span class=variable>progress-evt</span> <span class=variable>done-evt</span>)
(<code class=scheme>error</code> <span class=selfeval>"no successful peeks!"</span>))))
(<code class=scheme>read-char</code> <span class=variable>/dev/null-in</span>) <span class=comment>; => <code class=scheme><code class=scheme>eof</code></code></span>
(<code class=scheme>peek-char</code> <span class=variable>/dev/null-in</span>) <span class=comment>; => <code class=scheme><code class=scheme>eof</code></code></span>
(<code class=scheme>read-byte-or-special</code> <span class=variable>/dev/null-in</span>) <span class=comment>; => <code class=scheme><code class=scheme>eof</code></code></span>
(<code class=scheme>peek-byte-or-special</code> <span class=variable>/dev/null-in</span> <span class=selfeval>100</span>) <span class=comment>; => <code class=scheme><code class=scheme>eof</code></code></span>
<span class=comment>;; A port that produces a stream of 1s:</span>
(<span class=keyword>define</span> <span class=variable>infinite-ones</span>
(<code class=scheme>make-input-port</code>
<span class=keyword>'</span><span class=variable>ones</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span>)
(<code class=scheme>bytes-set!</code> <span class=variable>s</span> <span class=selfeval>0</span> (<code class=scheme>char->integer</code> <span class=selfeval>#\1</span>)) <span class=selfeval>1</span>)
<span class=selfeval>#f</span>
<code class=scheme>void</code>))
(<code class=scheme>read-string</code> <span class=selfeval>5</span> <span class=variable>infinite-ones</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"11111"</span></code></span>
<span class=comment>;; But we can't peek ahead arbitrarily far, because the</span>
<span class=comment>;; automatic peek must record the skipped bytes:</span>
(<code class=scheme>peek-string</code> <span class=selfeval>5</span> (<code class=scheme>expt</code> <span class=selfeval>2</span> <span class=selfeval>5000</span>) <span class=variable>infinite-ones</span>) <span class=comment>; => error: out of memory</span>
<span class=comment>;; An infinite stream of 1s with a specific peek procedure:</span>
(<span class=keyword>define</span> <span class=variable>infinite-ones</span>
(<span class=keyword>let</span> ([<span class=variable>one!</span> (<span class=keyword>lambda</span> (<span class=variable>s</span>)
(<code class=scheme>bytes-set!</code> <span class=variable>s</span> <span class=selfeval>0</span> (<code class=scheme>char->integer</code> <span class=selfeval>#\1</span>)) <span class=selfeval>1</span>)])
(<code class=scheme>make-input-port</code>
<span class=keyword>'</span><span class=variable>ones</span>
<span class=variable>one!</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>skip</span> <span class=variable>progress-evt</span>) (<span class=variable>one!</span> <span class=variable>s</span>))
<code class=scheme>void</code>)))
(<code class=scheme>read-string</code> <span class=selfeval>5</span> <span class=variable>infinite-ones</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"11111"</span></code></span>
<span class=comment>;; Now we can peek ahead arbitrarily far:</span>
(<code class=scheme>peek-string</code> <span class=selfeval>5</span> (<code class=scheme>expt</code> <span class=selfeval>2</span> <span class=selfeval>5000</span>) <span class=variable>infinite-ones</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"11111"</span></code></span>
<span class=comment>;; The port doesn't supply procedures to implement progress events:</span>
(<code class=scheme>port-provides-progress-evts?</code> <span class=variable>infinite-ones</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>#f</span></code></span>
(<code class=scheme>port-progress-evt</code> <span class=variable>infinite-ones</span>) <span class=comment>; error: no progress events</span>
<span class=comment>;; Non-byte port results:</span>
(<span class=keyword>define</span> <span class=variable>infinite-voids</span>
(<code class=scheme>make-input-port</code>
<span class=keyword>'</span><span class=variable>voids</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span>) (<span class=keyword>lambda</span> <span class=variable>args</span> <span class=keyword>'</span><code class=scheme>void</code>))
(<span class=keyword>lambda</span> (<span class=variable>skip</span> <span class=variable>s</span>) (<span class=keyword>lambda</span> <span class=variable>args</span> <span class=keyword>'</span><code class=scheme>void</code>))
<code class=scheme>void</code>))
(<code class=scheme>read-char</code> <span class=variable>infinite-voids</span>) <span class=comment>; => error: non-char in an unsupported context</span>
(<code class=scheme>read-char-or-special</code> <span class=variable>infinite-voids</span>) <span class=comment>; => <code class=schemeresponse><span class=keyword>'</span><code class=scheme>void</code></code></span>
<span class=comment>;; This port produces 0, 1, 2, 0, 1, 2, etc., but it is not</span>
<span class=comment>;; thread-safe, because multiple threads might read and change <code class=scheme><span class=variable>n</span></code>.</span>
(<span class=keyword>define</span> <span class=variable>mod3-cycle/one-thread</span>
(<span class=keyword>let*</span> ([<span class=variable>n</span> <span class=selfeval>2</span>]
[<span class=variable>mod!</span> (<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>delta</span>)
(<code class=scheme>bytes-set!</code> <span class=variable>s</span> <span class=selfeval>0</span> (<span class=variable>+</span> <span class=selfeval>48</span> (<code class=scheme>modulo</code> (<span class=variable>+</span> <span class=variable>n</span> <span class=variable>delta</span>) <span class=selfeval>3</span>)))
<span class=selfeval>1</span>)])
(<code class=scheme>make-input-port</code>
<span class=keyword>'</span><span class=variable>mod3-cycle/not-thread-safe</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span>)
(<span class=keyword>set!</span> <span class=variable>n</span> (<code class=scheme>modulo</code> (<code class=scheme>add1</code> <span class=variable>n</span>) <span class=selfeval>3</span>))
(<span class=variable>mod!</span> <span class=variable>s</span> <span class=selfeval>0</span>))
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>skip</span>)
(<span class=variable>mod!</span> <span class=variable>s</span> <span class=variable>skip</span>))
<code class=scheme>void</code>)))
(<code class=scheme>read-string</code> <span class=selfeval>5</span> <span class=variable>mod3-cycle/one-thread</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"01201"</span></code></span>
(<code class=scheme>peek-string</code> <span class=selfeval>5</span> (<code class=scheme>expt</code> <span class=selfeval>2</span> <span class=selfeval>5000</span>) <span class=variable>mod3-cycle/one-thread</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"20120"</span></code></span>
<span class=comment>;; Same thing, but thread-safe and kill-safe, and with progress</span>
<span class=comment>;; events. Only the server thread touches the stateful part</span>
<span class=comment>;; directly. (See the output port examples for a simpler thread-safe</span>
<span class=comment>;; example, but this one is more general.)</span>
(<span class=keyword>define</span> (<span class=variable>make-mod3-cycle</span>)
(<span class=keyword>define</span> <span class=variable>read-req-ch</span> (<code class=scheme>make-channel</code>))
(<span class=keyword>define</span> <span class=variable>peek-req-ch</span> (<code class=scheme>make-channel</code>))
(<span class=keyword>define</span> <span class=variable>progress-req-ch</span> (<code class=scheme>make-channel</code>))
(<span class=keyword>define</span> <span class=variable>commit-req-ch</span> (<code class=scheme>make-channel</code>))
(<span class=keyword>define</span> <span class=variable>close-req-ch</span> (<code class=scheme>make-channel</code>))
(<span class=keyword>define</span> <span class=variable>closed?</span> <span class=selfeval>#f</span>)
(<span class=keyword>define</span> <span class=variable>n</span> <span class=selfeval>0</span>)
(<span class=keyword>define</span> <span class=variable>progress-sema</span> <span class=selfeval>#f</span>)
(<span class=keyword>define</span> (<span class=variable>mod!</span> <span class=variable>s</span> <span class=variable>delta</span>)
(<code class=scheme>bytes-set!</code> <span class=variable>s</span> <span class=selfeval>0</span> (<span class=variable>+</span> <span class=selfeval>48</span> (<code class=scheme>modulo</code> (<span class=variable>+</span> <span class=variable>n</span> <span class=variable>delta</span>) <span class=selfeval>3</span>)))
<span class=selfeval>1</span>)
<span class=comment>;; ----------------------------------------</span>
<span class=comment>;; The server has a list of outstanding commit requests,</span>
<span class=comment>;; and it also must service each port operation (read, </span>
<span class=comment>;; progress-evt, etc.)</span>
(<span class=keyword>define</span> (<span class=variable>serve</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>)
(<code class=scheme>apply</code>
<code class=scheme>sync</code>
(<span class=variable>handle-evt</span> <span class=variable>read-req-ch</span> (<span class=variable>handle-read</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>))
(<span class=variable>handle-evt</span> <span class=variable>progress-req-ch</span> (<span class=variable>handle-progress</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>))
(<span class=variable>handle-evt</span> <span class=variable>commit-req-ch</span> (<span class=variable>add-commit</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>))
(<span class=variable>handle-evt</span> <span class=variable>close-req-ch</span> (<span class=variable>handle-close</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>))
(<code class=scheme>append</code>
(<code class=scheme>map</code> (<span class=variable>make-handle-response</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>) <span class=variable>response-evts</span>)
(<code class=scheme>map</code> (<span class=variable>make-handle-commit</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>) <span class=variable>commit-reqs</span>))))
<span class=comment>;; Read/peek request: fill in the string and commit</span>
(<span class=keyword>define</span> ((<span class=variable>handle-read</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>) <span class=variable>r</span>)
(<span class=keyword>let</span> ([<span class=variable>s</span> (<code class=scheme>car</code> <span class=variable>r</span>)]
[<span class=variable>skip</span> (<code class=scheme>cadr</code> <span class=variable>r</span>)]
[<span class=variable>ch</span> (<code class=scheme>caddr</code> <span class=variable>r</span>)]
[<span class=variable>nack</span> (<code class=scheme>cadddr</code> <span class=variable>r</span>)]
[<span class=variable>peek?</span> (<code class=scheme>cddddr</code> <span class=variable>r</span>)])
(<span class=keyword>unless</span> <span class=variable>closed?</span>
(<span class=variable>mod!</span> <span class=variable>s</span> <span class=variable>skip</span>)
(<span class=keyword>unless</span> <span class=variable>peek?</span>
(<span class=variable>commit!</span> <span class=selfeval>1</span>)))
<span class=comment>;; Add an event to respond:</span>
(<span class=variable>serve</span> <span class=variable>commit-reqs</span>
(<code class=scheme>cons</code> (<code class=scheme>choice-evt</code> <span class=variable>nack</span>
(<code class=scheme>channel-put-evt</code> <span class=variable>ch</span> (<span class=keyword>if</span> <span class=variable>closed?</span> <span class=selfeval>0</span> <span class=selfeval>1</span>)))
<span class=variable>response-evts</span>))))
<span class=comment>;; Progress request: send a peek evt for the current </span>
<span class=comment>;; progress-sema</span>
(<span class=keyword>define</span> ((<span class=variable>handle-progress</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>) <span class=variable>r</span>)
(<span class=keyword>let</span> ([<span class=variable>ch</span> (<code class=scheme>car</code> <span class=variable>r</span>)]
[<span class=variable>nack</span> (<code class=scheme>cdr</code> <span class=variable>r</span>)])
(<span class=keyword>unless</span> <span class=variable>progress-sema</span>
(<span class=keyword>set!</span> <span class=variable>progress-sema</span> (<code class=scheme>make-semaphore</code> (<span class=keyword>if</span> <span class=variable>closed?</span> <span class=selfeval>1</span> <span class=selfeval>0</span>))))
<span class=comment>;; Add an event to respond:</span>
(<span class=variable>serve</span> <span class=variable>commit-reqs</span>
(<code class=scheme>cons</code> (<code class=scheme>choice-evt</code> <span class=variable>nack</span>
(<code class=scheme>channel-put-evt</code>
<span class=variable>ch</span>
(<span class=variable>semaphore-peek-evt</span> <span class=variable>progress-sema</span>)))
<span class=variable>response-evts</span>))))
<span class=comment>;; Commit request: add the request to the list</span>
(<span class=keyword>define</span> ((<span class=variable>add-commit</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>) <span class=variable>r</span>)
(<span class=variable>serve</span> (<code class=scheme>cons</code> <span class=variable>r</span> <span class=variable>commit-reqs</span>) <span class=variable>response-evts</span>))
<span class=comment>;; Commit handling: watch out for progress, in which case</span>
<span class=comment>;; the response is a commit failure; otherwise, try</span>
<span class=comment>;; to sync for a commit. In either event, remove the</span>
<span class=comment>;; request from the list</span>
(<span class=keyword>define</span> ((<span class=variable>make-handle-commit</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>) <span class=variable>r</span>)
(<span class=keyword>let</span> ([<span class=variable>k</span> (<code class=scheme>car</code> <span class=variable>r</span>)]
[<span class=variable>progress-evt</span> (<code class=scheme>cadr</code> <span class=variable>r</span>)]
[<span class=variable>done-evt</span> (<code class=scheme>caddr</code> <span class=variable>r</span>)]
[<span class=variable>ch</span> (<code class=scheme>cadddr</code> <span class=variable>r</span>)]
[<span class=variable>nack</span> (<code class=scheme>cddddr</code> <span class=variable>r</span>)])
<span class=comment>;; Note: we don't check that k is <u><</u> the sum of</span>
<span class=comment>;; previous peeks, because the entire stream is actually</span>
<span class=comment>;; known, but we could send an exception in that case.</span>
(<code class=scheme>choice-evt</code>
(<span class=variable>handle-evt</span> <span class=variable>progress-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>x</span>)
(<code class=scheme>sync</code> <span class=variable>nack</span> (<code class=scheme>channel-put-evt</code> <span class=variable>ch</span> <span class=selfeval>#f</span>))
(<span class=variable>serve</span> (<code class=scheme>remq</code> <span class=variable>r</span> <span class=variable>commit-reqs</span>) <span class=variable>response-evts</span>)))
<span class=comment>;; Only create an event to satisfy done-evt if progress-evt</span>
<span class=comment>;; isn't already ready.</span>
<span class=comment>;; Afterward, if progress-evt becomes ready, then this</span>
<span class=comment>;; event-making function will be called again, because</span>
<span class=comment>;; the server controls all posts to progress-evt.</span>
(<span class=keyword>if</span> (<code class=scheme>sync/timeout</code> <span class=selfeval>0</span> <span class=variable>progress-evt</span>)
<span class=variable>never-evt</span>
(<span class=variable>handle-evt</span> <span class=variable>done-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>v</span>)
(<span class=variable>commit!</span> <span class=variable>k</span>)
(<code class=scheme>sync</code> <span class=variable>nack</span> (<code class=scheme>channel-put-evt</code> <span class=variable>ch</span> <span class=selfeval>#t</span>))
(<span class=variable>serve</span> (<code class=scheme>remq</code> <span class=variable>r</span> <span class=variable>commit-reqs</span>) <span class=variable>response-evts</span>)))))))
<span class=comment>;; Response handling: as soon as the respondee listens,</span>
<span class=comment>;; remove the response</span>
(<span class=keyword>define</span> ((<span class=variable>make-handle-response</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>) <span class=variable>evt</span>)
(<span class=variable>handle-evt</span> <span class=variable>evt</span>
(<span class=keyword>lambda</span> (<span class=variable>x</span>)
(<span class=variable>serve</span> <span class=variable>commit-reqs</span>
(<code class=scheme>remq</code> <span class=variable>evt</span> <span class=variable>response-evts</span>)))))
<span class=comment>;; Close handling: post the progress sema, if any, and set</span>
<span class=comment>;; the <code class=scheme><span class=variable>closed?</span></code> flag</span>
(<span class=keyword>define</span> ((<span class=variable>handle-close</span> <span class=variable>commit-reqs</span> <span class=variable>response-evts</span>) <span class=variable>r</span>)
(<span class=keyword>let</span> ([<span class=variable>ch</span> (<code class=scheme>car</code> <span class=variable>r</span>)]
[<span class=variable>nack</span> (<code class=scheme>cdr</code> <span class=variable>r</span>)])
(<span class=keyword>set!</span> <span class=variable>closed?</span> <span class=selfeval>#t</span>)
(<span class=keyword>when</span> <span class=variable>progress-sema</span>
(<code class=scheme>semaphore-post</code> <span class=variable>progress-sema</span>))
(<span class=variable>serve</span> <span class=variable>commit-reqs</span>
(<code class=scheme>cons</code> (<code class=scheme>choice-evt</code> <span class=variable>nack</span>
(<code class=scheme>channel-put-evt</code> <span class=variable>ch</span> (<code class=scheme>void</code>)))
<span class=variable>response-evts</span>))))
<span class=comment>;; Helper for reads and post-peek commits:</span>
(<span class=keyword>define</span> (<span class=variable>commit!</span> <span class=variable>k</span>)
(<span class=keyword>when</span> <span class=variable>progress-sema</span>
(<code class=scheme>semaphore-post</code> <span class=variable>progress-sema</span>)
(<span class=keyword>set!</span> <span class=variable>progress-sema</span> <span class=selfeval>#f</span>))
(<span class=keyword>set!</span> <span class=variable>n</span> (<span class=variable>+</span> <span class=variable>n</span> <span class=variable>k</span>)))
<span class=comment>;; Start the server thread:</span>
(<span class=keyword>define</span> <span class=variable>server-thread</span> (<code class=scheme>thread</code> (<span class=keyword>lambda</span> () (<span class=variable>serve</span> <code class=scheme>null</code> <code class=scheme>null</code>))))
<span class=comment>;; ----------------------------------------</span>
<span class=comment>;; Client-side helpers:</span>
(<span class=keyword>define</span> (<span class=variable>req-evt</span> <span class=variable>f</span>)
(<code class=scheme>nack-guard-evt</code>
(<span class=keyword>lambda</span> (<span class=variable>nack</span>)
<span class=comment>;; Be sure that the server thread is running:</span>
(<code class=scheme>thread-resume</code> <span class=variable>server-thread</span> (<code class=scheme>current-thread</code>))
<span class=comment>;; Create a channel to hold the reply:</span>
(<span class=keyword>let</span> ([<span class=variable>ch</span> (<code class=scheme>make-channel</code>)])
(<span class=variable>f</span> <span class=variable>ch</span> <span class=variable>nack</span>)
<span class=variable>ch</span>))))
(<span class=keyword>define</span> (<span class=variable>read-or-peek-evt</span> <span class=variable>s</span> <span class=variable>skip</span> <span class=variable>peek?</span>)
(<span class=variable>req-evt</span> (<span class=keyword>lambda</span> (<span class=variable>ch</span> <span class=variable>nack</span>)
(<code class=scheme>channel-put</code> <span class=variable>read-req-ch</span> (<code class=scheme>list*</code> <span class=variable>s</span> <span class=variable>skip</span> <span class=variable>ch</span> <span class=variable>nack</span> <span class=variable>peek?</span>)))))
<span class=comment>;; Make the port:</span>
(<code class=scheme>make-input-port</code> <span class=keyword>'</span><span class=variable>mod3-cycle</span>
<span class=comment>;; Each handler for the port just sends</span>
<span class=comment>;; a request to the server</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span>) (<span class=variable>read-or-peek-evt</span> <span class=variable>s</span> <span class=selfeval>0</span> <span class=selfeval>#f</span>))
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>skip</span>) (<span class=variable>read-or-peek-evt</span> <span class=variable>s</span> <span class=variable>skip</span> <span class=selfeval>#t</span>))
(<span class=keyword>lambda</span> () <span class=comment>; close</span>
(<code class=scheme>sync</code> (<span class=variable>req-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>ch</span> <span class=variable>nack</span>)
(<code class=scheme>channel-put</code> <span class=variable>progress-req-ch</span> (<code class=scheme>list*</code> <span class=variable>ch</span> <span class=variable>nack</span>))))))
(<span class=keyword>lambda</span> () <span class=comment>; progress-evt</span>
(<code class=scheme>sync</code> (<span class=variable>req-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>ch</span> <span class=variable>nack</span>)
(<code class=scheme>channel-put</code> <span class=variable>progress-req-ch</span> (<code class=scheme>list*</code> <span class=variable>ch</span> <span class=variable>nack</span>))))))
(<span class=keyword>lambda</span> (<span class=variable>k</span> <span class=variable>progress-evt</span> <span class=variable>done-evt</span>) <span class=comment>; commit</span>
(<code class=scheme>sync</code> (<span class=variable>req-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>ch</span> <span class=variable>nack</span>)
(<code class=scheme>channel-put</code> <span class=variable>commit-req-ch</span>
(<code class=scheme>list*</code> <span class=variable>k</span> <span class=variable>progress-evt</span> <span class=variable>done-evt</span> <span class=variable>ch</span> <span class=variable>nack</span>))))))))
(<span class=keyword>let</span> ([<span class=variable>mod3-cycle</span> (<span class=variable>make-mod3-cycle</span>)])
(<span class=keyword>let</span> ([<span class=variable>result1</span> <span class=selfeval>#f</span>]
[<span class=variable>result2</span> <span class=selfeval>#f</span>])
(<span class=keyword>let</span> ([<span class=variable>t1</span> (<code class=scheme>thread</code> (<span class=keyword>lambda</span> ()
(<span class=keyword>set!</span> <span class=variable>result1</span> (<code class=scheme>read-string</code> <span class=selfeval>5</span> <span class=variable>mod3-cycle</span>))))]
[<span class=variable>t2</span> (<code class=scheme>thread</code> (<span class=keyword>lambda</span> ()
(<span class=keyword>set!</span> <span class=variable>result2</span> (<code class=scheme>read-string</code> <span class=selfeval>5</span> <span class=variable>mod3-cycle</span>))))])
(<code class=scheme>thread-wait</code> <span class=variable>t1</span>)
(<code class=scheme>thread-wait</code> <span class=variable>t2</span>)
(<code class=scheme>string-append</code> <span class=variable>result1</span> <span class=selfeval>","</span> <span class=variable>result2</span>))) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"02120,10201"</span></code>, maybe</span>
(<span class=keyword>let</span> ([<span class=variable>s</span> (<code class=scheme>make-bytes</code> <span class=selfeval>1</span>)]
[<span class=variable>progress-evt</span> (<code class=scheme>port-progress-evt</code> <span class=variable>mod3-cycle</span>)])
(<code class=scheme>peek-bytes-avail!</code> <span class=variable>s</span> <span class=selfeval>0</span> <span class=variable>progress-evt</span> <span class=variable>mod3-cycle</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>1</span></code></span>
<span class=variable>s</span> <span class=comment>; => <code class=schemeresponse><span class=selfeval>#</span><span class=selfeval>"1"</span></code></span>
(<code class=scheme>port-commit-peeked</code> <span class=selfeval>1</span> <span class=variable>progress-evt</span> (<code class=scheme>make-semaphore</code> <span class=selfeval>1</span>)
<span class=variable>mod3-cycle</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>#t</span></code></span>
(<code class=scheme>sync/timeout</code> <span class=selfeval>0</span> <span class=variable>progress-evt</span>) <span class=comment>; => <code class=scheme><span class=variable>progress-evt</span></code></span>
(<code class=scheme>peek-bytes-avail!</code> <span class=variable>s</span> <span class=selfeval>0</span> <span class=variable>progress-evt</span> <span class=variable>mod3-cycle</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>0</span></code></span>
(<code class=scheme>port-commit-peeked</code> <span class=selfeval>1</span> <span class=variable>progress-evt</span> (<code class=scheme>make-semaphore</code> <span class=selfeval>1</span>)
<span class=variable>mod3-cycle</span>)) <span class=comment>; => <code class=schemeresponse><span class=selfeval>#f</span></code></span>
(<code class=scheme>close-input-port</code> <span class=variable>mod3-cycle</span>))
</pre></div><p></p>
<p>
</p>
<a name="node_sec_11.1.7.2"></a>
<h4><a href="mzscheme.html#node_toc_node_sec_11.1.7.2">11.1.7.2 Custom Output</a></h4>
<p><a name="node_idx_1986"></a><a name="node_kw_definitionmake-output-port"></a><code class=scheme>(make-output-port</code><tt> </tt><code class=scheme><span class=variable>name-v evt write-proc close-proc</span></code><tt> </tt>[<code class=scheme><span class=variable>optional-write-special-proc optional-write-evt-proc optional-special-evt-proc optional-location-proc count-lines!-proc init-position optional-buffer-mode-proc</span></code>]<code class=scheme>)</code>
creates an output port. The port is immediately open for writing. If
<code class=scheme><span class=variable>close-proc</span></code> procedure has no side effects, then the port need
not be explicitly closed. The port can buffer data within its
<code class=scheme><span class=variable>write-proc</span></code> and <code class=scheme><span class=variable>optional-write-special-proc</span></code> procedures.</p>
<p>
</p>
<ul><p>
</p>
<li><p><code class=scheme><span class=variable>name-v</span></code> -- the name for the output port, which is
reported by <code class=scheme>object-name</code> (see section <a href="mzscheme-Z-H-6.html#node_sec_6.2.4">6.2.4</a>).</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>evt</span></code> -- a synchronization event (see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>;
e.g., a semaphore or another port). The event is used in place of
the output port when the port is supplied to synchronization
procedures like <code class=scheme>sync</code>. Thus, the event should be
unblocked when the port is ready for writing at least one byte
without blocking, or ready to make progress in flushing an
internal buffer without blocking. The event must not unblock
unless the port is ready for writing; otherwise, the guarantees of
<code class=scheme><code class=scheme>sync</code></code> will be broken for the output port. Use
<code class=scheme>always-evt</code> if writes to the port always succeed without
blocking.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>write-proc</span></code> -- a procedure of five arguments:
</p>
<ul><p>
</p>
<li><p>an immutable byte string containing bytes to write;</p>
<p>
</p>
<li><p>a non-negative exact integer for a starting offset
(inclusive) into the byte string;</p>
<p>
</p>
<li><p>a non-negative exact integer for an ending offset
(exclusive) into the byte string;</p>
<p>
</p>
<li><p>a boolean; <code class=scheme><span class=selfeval>#f</span></code> indicates that the port is allowed
to keep the written bytes in a buffer, and that it is
allowed to block indefinitely; <code class=scheme><span class=selfeval>#t</span></code> indicates that the
write should not block, and that the port should attempt to flush
its buffer and completely write new bytes instead of
buffering them;</p>
<p>
</p>
<li><p>a boolean; <code class=scheme><span class=selfeval>#t</span></code> indicates that if the port blocks
for a write, then it should enable breaks while blocking (e.g.,
using <code class=scheme>sync/enable-break</code>; this argument is always
<code class=scheme><span class=selfeval>#f</span></code> if the fourth argument is <code class=scheme><span class=selfeval>#t</span></code>.</p>
<p>
</p>
</ul><p>
The procedure returns one of the following:
</p>
<ul><p>
</p>
<li><p>a non-negative exact integer representing the number of
bytes written or buffered;</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>#f</span></code> if no bytes could be written, perhaps because
the internal buffer could not be completely flushed;</p>
<p>
</p>
<li><p>a synchronizable event (see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>) that acts like
the result of <code class=scheme>write-bytes-avail-evt</code> to complete the
write.</p>
<p>
</p>
</ul><p>
Since <code class=scheme><span class=variable>write-proc</span></code> can produce an event, an acceptable
implementation of <code class=scheme><span class=variable>write-proc</span></code> is to pass its first three
arguments to the port's <code class=scheme><span class=variable>optional-write-evt-proc</span></code>. Some port
implementors, however, may choose not to provide
<code class=scheme><span class=variable>optional-write-evt-proc</span></code> (perhaps because writes cannot be
made atomic), or may implement <code class=scheme><span class=variable>write-proc</span></code> to
enable a fast path for non-blocking writes or to
enable buffering.</p>
<p>
From a user's perspective, the difference between buffered and
completely written data is (1) buffered data can be lost in the
future due to a failed write, and (2) <code class=scheme>flush-output</code> forces
all buffered data to be completely written. Under no circumstances
is buffering required.</p>
<p>
If the start and end indices are the same, then the fourth
argument to <code class=scheme><span class=variable>write-proc</span></code> will be <code class=scheme><span class=selfeval>#f</span></code>, and the write
request is actually a flush request for the port's buffer (if
any), and the result should be <code class=scheme><span class=selfeval>0</span></code> for a successful flush
(or if there is no buffer).</p>
<p>
The result should never be <code class=scheme><span class=selfeval>0</span></code> if the start and end indices
are different, otherwise the <a name="node_idx_1988"></a><code class=scheme>exn:fail:contract</code> exception is raised.
If a returned integer is larger than the supplied byte-string
range, the <a name="node_idx_1990"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
The <code class=scheme><span class=selfeval>#f</span></code> result should be avoided, unless the next write
attempt is likely to work. Otherwise, if data cannot be written,
return an event instead.</p>
<p>
An event returned by <code class=scheme><span class=variable>write-proc</span></code> can return <code class=scheme><span class=selfeval>#f</span></code> or
another event like itself, in contrast to events produced by
<code class=scheme>write-bytes-avail-evt</code> or <code class=scheme><span class=variable>optional-write-evt-proc</span></code>.
A writing process loops with <code class=scheme><code class=scheme>sync</code></code> until it obtains a
non-event result.</p>
<p>
The <code class=scheme><span class=variable>write-proc</span></code> procedure is always called with breaks
disabled, independent of whether breaks were enabled when the write
was requested by a client of the port. If breaks were enabled for
a blocking operation, then the fifth argument to <code class=scheme><span class=variable>write-proc</span></code>
will be <code class=scheme><span class=selfeval>#t</span></code>, which indicates that <code class=scheme><span class=variable>write-proc</span></code> should
re-enable breaks while blocking.</p>
<p>
If the writing procedure raises an exception, due either to write
or commit operations, it must not have committed any bytes
(though it may have committed previously buffered bytes).</p>
<p>
A port's writing procedure may be called in multiple threads
simultaneously (if the port is accessible in multiple
threads). The port is responsible for its own internal
synchronization. Note that improper implementation of such
synchronization mechanisms might cause a non-blocking write
procedure to block.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>close-proc</span></code> -- a procedure of zero arguments that is
called to close the port. The port is not considered closed until
the closing procedure returns. The port's procedures will never be
used again via the port after it is closed. However, the closing
procedure can be called simultaneously in multiple threads (if the
port is accessible in multiple threads), and it may be called
during a call to the other procedures in another thread; in the
latter case, any outstanding writes or flushes should be
terminated immediately with an error.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-write-special-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> (the
default), or a procedure to handle <code class=scheme>write-special</code> calls
for the port. If <code class=scheme><span class=selfeval>#f</span></code>, then the port does not support
special output, and <code class=scheme>port-writes-special?</code> will return
<code class=scheme><span class=selfeval>#f</span></code> when applied to the port.</p>
<p>
If a procedure is supplied, it takes three arguments: the special
value to write, a boolean that is <code class=scheme><span class=selfeval>#f</span></code> if the procedure can
buffer the special value and block indefinitely, and a boolean
that is <code class=scheme><span class=selfeval>#t</span></code> if the procedure should enable breaks while
blocking. The result is one of the following:
</p>
<ul><p>
</p>
<li><p>a non-event true value, which indicates that the special is
written;</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>#f</span></code> if the special could not be written, perhaps
because an internal buffer could not be completely flushed;</p>
<p>
</p>
<li><p>a synchronizable event (see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>) that acts like
the result of <code class=scheme>write-special-evt</code> to complete the write.</p>
<p>
</p>
</ul><p>
Since <code class=scheme><span class=variable>optional-write-special-proc</span></code> can return an event,
passing the first argument to an implementation of
<code class=scheme><span class=variable>option-write-special-evt-proc</span></code> is acceptable as an
<code class=scheme><span class=variable>optional-write-special-proc</span></code>.</p>
<p>
As for <code class=scheme><span class=variable>write-proc</span></code>, the <code class=scheme><span class=selfeval>#f</span></code> result is discouraged,
since it can lead to busy waiting. Also as for <code class=scheme><span class=variable>write-proc</span></code>,
an event produced by <code class=scheme><span class=variable>optional-write-special-proc</span></code> is allowed
to produce <code class=scheme><span class=selfeval>#f</span></code> or another event like itself. The
<code class=scheme><span class=variable>optional-write-special-proc</span></code> procedure is always called with
breaks disabled, independent of whether breaks were enabled when
the write was requested by a client of the port.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-write-evt-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> (the
default) or a procedure of three arguments:
</p>
<ul><p>
</p>
<li><p>an immutable byte string containing bytes to write;</p>
<p>
</p>
<li><p>a non-negative exact integer for a starting offset
(inclusive) into the byte string, and</p>
<p>
</p>
<li><p>a non-negative exact integer for an ending offset
(exclusive) into the byte string.</p>
<p>
</p>
</ul><p>
The result is a synchronizable event (see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>) to act as
the result of <code class=scheme>write-bytes-avail-evt</code> for the port (i.e.,
to complete a write or flush), which becomes available only as
data is committed to the port's underlying device, and whose
result is the number of bytes written.</p>
<p>
If <code class=scheme><span class=variable>optional-write-evt-proc</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then
<code class=scheme>port-writes-atomic?</code> will produce <code class=scheme><span class=selfeval>#f</span></code> with applied
to the port, and the port will not be a valid argument to
procedures such as <code class=scheme>write-bytes-avail-evt</code>.</p>
<p>
Otherwise, an event returned by <code class=scheme><span class=variable>optional-write-evt-proc</span></code> must
not cause data to be written to the port unless the event is
chosen in a synchronization, and it must write to the port if the
event is chosen (i.e., the write must appear atomic with respect
to the synchronization).</p>
<p>
If the event's result integer is larger than the supplied
byte-string range, the <a name="node_idx_1992"></a><code class=scheme>exn:fail:contract</code> exception is raised by a wrapper
on the event. If the start and end indices are the same (i.e., no
bytes are to be written), then the event should produce <code class=scheme><span class=selfeval>0</span></code>
when the buffer is completely flushed. (If the port has no buffer,
then it is effectively always flushed.)</p>
<p>
If the event raises an exception, due either to write or commit
operations, it must not have committed any new bytes (though it
may have committed previously buffered bytes).</p>
<p>
Naturally, a port's events may be used in multiple threads
simultaneously (if the port is accessible in multiple
threads). The port is responsible for its own internal
synchronization.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-write-special-evt-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code>
(the default), or a procedure to handle <code class=scheme>write-special-evt</code>
calls for the port. This argument must be <code class=scheme><span class=selfeval>#f</span></code> if either
<code class=scheme><span class=variable>optional-write-special-proc</span></code> or <code class=scheme><span class=variable>optional-write-evt-proc</span></code>
is <code class=scheme><span class=selfeval>#f</span></code>, and it must be a procedure if both of those
arguments are procedures.</p>
<p>
If it is a procedure, it takes one argument: the special value to
write. The resulting event (with its constraints) is analogous to
the result of <code class=scheme><span class=variable>optional-write-evt-proc</span></code>.</p>
<p>
If the event raises an exception, due either to write or commit
operations, it must not have committed the special value (though
it may have committed previously buffered bytes and values).</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-location-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> (the
default), or a procedure that takes no arguments and returns three
values: the line number for the next item written to the port's
stream (a positive number or <code class=scheme><span class=selfeval>#f</span></code>), the column number for
the next item written to port's stream (a non-negative number or
<code class=scheme><span class=selfeval>#f</span></code>), and the position for the next item written to port's
stream (a positive number or <code class=scheme><span class=selfeval>#f</span></code>). See also
section <a href="#node_sec_11.2.1.1">11.2.1.1</a>.</p>
<p>
This procedure is only called if line counting is enabled for the
port via <code class=scheme>port-count-lines!</code> (in which case
<code class=scheme><span class=variable>count-lines!-proc</span></code> is called).</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>count-lines!-proc</span></code> -- a procedure of no arguments
that is called if and when line counting is enabled for the port.
The default procedure is <code class=scheme>void</code>.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>init-position</span></code> -- an exact, positive integer that
determines the position of the port's first output item, used when
line counting is <em>not</em> enabled for the port. The default is
<code class=scheme><span class=selfeval>1</span></code>.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>optional-buffer-mode-proc</span></code> -- either <code class=scheme><span class=selfeval>#f</span></code> (the
default) or a procedure that accepts zero or one arguments. If
<code class=scheme><span class=variable>optional-buffer-mode-proc</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then the resulting
port does not support a buffer-mode setting. Otherwise, the
procedure is called with one symbol argument (<code class=scheme><span class=selfeval>'block</span></code>,
<code class=scheme><span class=selfeval>'line</span></code>, or <code class=scheme><span class=selfeval>'none</span></code>) to set the buffer mode, and it is
called with zero arguments to get the current buffer mode. In the
latter case, the result must be <code class=scheme><span class=selfeval>'block</span></code>, <code class=scheme><span class=selfeval>'line</span></code>,
<code class=scheme><span class=selfeval>'none</span></code>, or <code class=scheme><span class=selfeval>#f</span></code> (unknown). See section <a href="#node_sec_11.1.6">11.1.6</a>
for more information on buffer modes.</p>
<p>
</p>
</ul><p></p>
<p>
Examples:
</p>
<div align=left><pre class=scheme><span class=comment>;; A port that writes anything to nowhere:</span>
(<span class=keyword>define</span> <span class=variable>/dev/null-out</span>
(<code class=scheme>make-output-port</code>
<span class=keyword>'</span><code class=scheme>null</code>
<span class=variable>always-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span> <span class=variable>non-block?</span> <span class=variable>breakable?</span>) (<span class=variable>-</span> <span class=variable>end</span> <span class=variable>start</span>))
<code class=scheme>void</code>
(<span class=keyword>lambda</span> (<span class=variable>special</span> <span class=variable>non-block?</span> <span class=variable>breakable?</span>) <span class=selfeval>#t</span>)
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span>) (<span class=variable>wrap-evt</span>
<span class=variable>always-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>x</span>)
(<span class=variable>-</span> <span class=variable>end</span> <span class=variable>start</span>))))
(<span class=keyword>lambda</span> (<span class=variable>special</span>) <span class=variable>always-evt</span>)))
(<code class=scheme>display</code> <span class=selfeval>"hello"</span> <span class=variable>/dev/null-out</span>) <span class=comment>; => void</span>
(<span class=variable>write-bytes-avail</span> <span class=selfeval>#</span><span class=selfeval>"hello"</span> <span class=variable>/dev/null-out</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>5</span></code></span>
(<span class=variable>write-special</span> <span class=keyword>'</span><span class=variable>hello</span> <span class=variable>/dev/null-out</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>#t</span></code></span>
(<code class=scheme>sync</code> (<span class=variable>write-bytes-avail-evt</span> <span class=selfeval>#</span><span class=selfeval>"hello"</span> <span class=variable>/dev/null-out</span>)) <span class=comment>; => <code class=schemeresponse><span class=selfeval>5</span></code></span>
<span class=comment>;; A part that accumulates bytes as characters in a list,</span>
<span class=comment>;; but not in a thread-safe way:</span>
(<span class=keyword>define</span> <span class=variable>accum-list</span> <code class=scheme>null</code>)
(<span class=keyword>define</span> <span class=variable>accumulator/not-thread-safe</span>
(<code class=scheme>make-output-port</code>
<span class=keyword>'</span><span class=variable>accum/not-thread-safe</span>
<span class=variable>always-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span> <span class=variable>non-block?</span> <span class=variable>breakable?</span>)
(<span class=keyword>set!</span> <span class=variable>accum-list</span>
(<code class=scheme>append</code> <span class=variable>accum-list</span>
(<code class=scheme>map</code> <code class=scheme>integer->char</code>
(<span class=variable>bytes->list</span> (<span class=variable>subbytes</span> <span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span>)))))
(<span class=variable>-</span> <span class=variable>end</span> <span class=variable>start</span>))
<code class=scheme>void</code>))
(<code class=scheme>display</code> <span class=selfeval>"hello"</span> <span class=variable>accumulator/not-thread-safe</span>)
<span class=variable>accum-list</span> <span class=comment>; => <code class=scheme><span class=keyword>'</span>(<span class=selfeval>#\h</span> <span class=selfeval>#\e</span> <span class=selfeval>#\l</span> <span class=selfeval>#\l</span> <span class=selfeval>#\o</span>)</code></span>
<span class=comment>;; Same as before, but with simple thread-safety:</span>
(<span class=keyword>define</span> <span class=variable>accum-list</span> <code class=scheme>null</code>)
(<span class=keyword>define</span> <span class=variable>accumulator</span>
(<span class=keyword>let*</span> ([<span class=variable>lock</span> (<code class=scheme>make-semaphore</code> <span class=selfeval>1</span>)]
[<span class=variable>lock-peek-evt</span> (<span class=variable>semaphore-peek-evt</span> <span class=variable>lock</span>)])
(<code class=scheme>make-output-port</code>
<span class=keyword>'</span><span class=variable>accum</span>
<span class=variable>lock-peek-evt</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span> <span class=variable>non-block?</span> <span class=variable>breakable?</span>)
(<span class=keyword>if</span> (<code class=scheme>semaphore-try-wait?</code> <span class=variable>lock</span>)
(<span class=keyword>begin</span>
(<span class=keyword>set!</span> <span class=variable>accum-list</span>
(<code class=scheme>append</code> <span class=variable>accum-list</span>
(<code class=scheme>map</code> <code class=scheme>integer->char</code>
(<span class=variable>bytes->list</span> (<span class=variable>subbytes</span> <span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span>)))))
(<code class=scheme>semaphore-post</code> <span class=variable>lock</span>)
(<span class=variable>-</span> <span class=variable>end</span> <span class=variable>start</span>))
<span class=comment>;; Cheap strategy: block until the list is unlocked,</span>
<span class=comment>;; then return 0, so we get called again</span>
(<span class=variable>wrap-evt</span>
<span class=variable>lock-peek</span>
(<span class=keyword>lambda</span> (<span class=variable>x</span>) <span class=selfeval>0</span>))))
<code class=scheme>void</code>)))
(<code class=scheme>display</code> <span class=selfeval>"hello"</span> <span class=variable>accumulator</span>)
<span class=variable>accum-list</span> <span class=comment>; => <code class=scheme><span class=keyword>'</span>(<span class=selfeval>#\h</span> <span class=selfeval>#\e</span> <span class=selfeval>#\l</span> <span class=selfeval>#\l</span> <span class=selfeval>#\o</span>)</code></span>
<span class=comment>;; A port that transforms data before sending it on</span>
<span class=comment>;; to another port. Atomic writes exploit the</span>
<span class=comment>;; underlying port's ability for atomic writes.</span>
(<span class=keyword>define</span> (<span class=variable>make-latin-1-capitalize</span> <span class=variable>port</span>)
(<span class=keyword>define</span> (<span class=variable>byte-upcase</span> <span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span>)
(<span class=variable>list->bytes</span>
(<code class=scheme>map</code> (<span class=keyword>lambda</span> (<span class=variable>b</span>) (<code class=scheme>char->integer</code>
(<code class=scheme>char-upcase</code>
(<code class=scheme>integer->char</code> <span class=variable>b</span>))))
(<span class=variable>bytes->list</span> (<span class=variable>subbytes</span> <span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span>)))))
(<code class=scheme>make-output-port</code>
<span class=keyword>'</span><span class=variable>byte-upcase</span>
<span class=comment>;; This port is ready when the original is ready:</span>
<span class=variable>port</span>
<span class=comment>;; Writing procedure:</span>
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span> <span class=variable>non-block?</span> <span class=variable>breakable?</span>)
(<span class=keyword>let</span> ([<span class=variable>s</span> (<span class=variable>byte-upcase</span> <span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span>)])
(<span class=keyword>if</span> <span class=variable>non-block?</span>
(<span class=variable>write-bytes-avail*</span> <span class=variable>s</span> <span class=variable>port</span>)
(<span class=keyword>begin</span>
(<code class=scheme>display</code> <span class=variable>s</span> <span class=variable>port</span>)
(<code class=scheme>bytes-length</code> <span class=variable>s</span>)))))
<span class=comment>;; Close procedure --- close original port:</span>
(<span class=keyword>lambda</span> () (<code class=scheme>close-output-port</code> <span class=variable>port</span>))
<span class=selfeval>#f</span>
<span class=comment>;; Write event:</span>
(<span class=keyword>and</span> (<span class=variable>port-writes-atomic?</span> <span class=variable>port</span>)
(<span class=keyword>lambda</span> (<span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span>)
(<span class=variable>write-bytes-avail-evt</span> (<span class=variable>byte-upcase</span> <span class=variable>s</span> <span class=variable>start</span> <span class=variable>end</span>) <span class=variable>port</span>)))))
(<span class=keyword>define</span> <span class=variable>orig-port</span> (<code class=scheme>open-output-string</code>))
(<span class=keyword>define</span> <span class=variable>cap-port</span> (<span class=variable>make-latin-1-capitalize</span> <span class=variable>orig-port</span>))
(<code class=scheme>display</code> <span class=selfeval>"Hello"</span> <span class=variable>cap-port</span>)
(<code class=scheme>get-output-string</code> <span class=variable>orig-port</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"HELLO"</span></code></span>
(<code class=scheme>sync</code> (<span class=variable>write-bytes-avail-evt</span> <span class=selfeval>#</span><span class=selfeval>"Bye"</span> <span class=variable>cap-port</span>)) <span class=comment>; => <code class=schemeresponse><span class=selfeval>3</span></code></span>
(<code class=scheme>get-output-string</code> <span class=variable>orig-port</span>) <span class=comment>; => <code class=schemeresponse><span class=selfeval>"HELLOBYE"</span></code></span>
</pre></div><p></p>
<p>
</p>
<a name="node_sec_11.2"></a>
<h2><a href="mzscheme.html#node_toc_node_sec_11.2">11.2 Reading and Writing</a></h2>
<p><a name="node_idx_1994"></a></p>
<p>
MzScheme's support for reading and writing includes many extensions
compared to <em>R5RS</em>, both at the level of individual bytes and
characters and at the level of S-expressions.</p>
<p>
</p>
<a name="node_sec_11.2.1"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.1">11.2.1 Reading Bytes, Characters, and Strings</a></h3>
<p></p>
<p>
In addition to the standard reading procedures, MzScheme provides
byte-reading procedure, block-reading procedures such as
<code class=scheme><code class=scheme>read-line</code></code>, and more.
</p>
<ul><p>
</p>
<li><p><a name="node_idx_1996"></a><a name="node_kw_definitionread-line"></a><code class=scheme>(read-line</code><tt> </tt>[<code class=scheme><span class=variable>input-port mode-symbol</span></code>]<code class=scheme>)</code> returns a string
containing the next line of bytes from <code class=scheme><span class=variable>input-port</span></code>. If
<code class=scheme><span class=variable>input-port</span></code> is omitted, the current input port is used.</p>
<p>
Characters are read from <code class=scheme><span class=variable>input-port</span></code> until a line separator or
an end-of-file is read. The line separator is not included in the
result string (but it is removed from the port's stream). If no
characters are read before an end-of-file is encountered, <code class=scheme><code class=scheme>eof</code></code>
is returned.</p>
<p>
The <code class=scheme><span class=variable>mode-symbol</span></code> argument determines the line separator(s). It
must be one of the following symbols:
</p>
<ul><p>
</p>
<li><p><code class=scheme><span class=selfeval>'linefeed</span></code><a name="node_idx_1998"></a> breaks lines on linefeed characters;
this is the default.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'return</span></code><a name="node_idx_2000"></a> breaks lines on return characters.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'return-linefeed</span></code><a name="node_idx_2002"></a> breaks lines on
return-linefeed combinations. If a return character is not followed
by a linefeed character, it is included in the result string;
similarly, a linefeed that is not preceded by a return is included
in the result string.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'any</span></code><a name="node_idx_2004"></a> breaks lines on any of a return
character, linefeed character, or return-linefeed combination. If a
return character is followed by a linefeed character, the two are
treated as a combination.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'any-one</span></code><a name="node_idx_2006"></a> breaks lines on either a return or
linefeed character, without recognizing return-linefeed
combinations.</p>
<p>
</p>
</ul><p>
Return and linefeed characters are detected after the conversions that
are automatically performed when reading a file in text mode. For
example, reading a file in text mode under Windows automatically
changes return-linefeed combinations to a linefeed. Thus, when a file
is opened in text mode, <code class=scheme><span class=selfeval>'linefeed</span></code> is usually the appropriate
<code class=scheme><code class=scheme>read-line</code></code> mode.</p>
<p>
</p>
<li><p><a name="node_idx_2008"></a><a name="node_kw_definitionread-bytes-line"></a><code class=scheme>(read-bytes-line</code><tt> </tt>[<code class=scheme><span class=variable>input-port mode-symbol</span></code>]<code class=scheme>)</code> is analogous to
<code class=scheme>read-line</code>, but it reads bytes and produces a byte string.</p>
<p>
</p>
<li><p><a name="node_idx_2010"></a><a name="node_kw_definitionread-string"></a><code class=scheme>(read-string</code><tt> </tt><code class=scheme><span class=variable>k</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code> returns a string containing
the next <code class=scheme><span class=variable>k</span></code> characters from <code class=scheme><span class=variable>input-port</span></code>. The default value
of <code class=scheme><span class=variable>input-port</span></code> is the current input port.</p>
<p>
If <code class=scheme><span class=variable>k</span></code> is <code class=scheme><span class=selfeval>0</span></code>, then the empty string is
returned. Otherwise, if fewer than <code class=scheme><span class=variable>k</span></code> characters are available
before an end-of-file is encountered, then the returned string will
contain only those characters before the end-of-file (i.e., the
returned string's length will be less than <code class=scheme><span class=variable>k</span></code>). <a name="node_call_footnote_31"></a><a href="#node_footnote_31"><sup><small>31</small></sup></a> If no characters are available before an end-of-file,
then <code class=scheme><code class=scheme>eof</code></code> is returned.</p>
<p>
If an error occurs during reading, some characters may be lost (i.e.,
if <code class=scheme><code class=scheme>read-string</code></code> successfully reads some characters before
encountering an error, the characters are dropped.)</p>
<p>
</p>
<li><p><a name="node_idx_2012"></a><a name="node_kw_definitionread-bytes"></a><code class=scheme>(read-bytes</code><tt> </tt><code class=scheme><span class=variable>k</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code> is analogous to
<code class=scheme>read-string</code>, but it reads bytes and produces a byte string.</p>
<p>
</p>
<li><p><a name="node_idx_2014"></a><a name="node_kw_definitionread-string!"></a><code class=scheme>(read-string!</code><tt> </tt><code class=scheme><span class=variable>string</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port start-k end-k</span></code>]<code class=scheme>)</code> reads
characters from <code class=scheme><span class=variable>input-port</span></code> like <code class=scheme>read-string</code>, but puts them
into <code class=scheme><span class=variable>string</span></code> starting from index <code class=scheme><span class=variable>start-k</span></code> (inclusive) up to
<code class=scheme><span class=variable>end-k</span></code> (exclusive). The default value of <code class=scheme><span class=variable>input-port</span></code> is
the current input port. The default value of <code class=scheme><span class=variable>start-k</span></code> is
<code class=scheme><span class=selfeval>0</span></code>. The default value of <code class=scheme><span class=variable>end-k</span></code> is the length of the
<code class=scheme><span class=variable>string</span></code>. Like <code class=scheme><code class=scheme>substring</code></code>, the
<a name="node_idx_2016"></a><code class=scheme>exn:fail:contract</code> exception is raised if <code class=scheme><span class=variable>start-k</span></code> or <code class=scheme><span class=variable>end-k</span></code>
is out-of-range for <code class=scheme><span class=variable>string</span></code>.</p>
<p>
If the difference between <code class=scheme><span class=variable>start-k</span></code> and <code class=scheme><span class=variable>end-k</span></code> is
<code class=scheme><span class=selfeval>0</span></code>, then <code class=scheme><span class=selfeval>0</span></code> is returned and <code class=scheme><span class=variable>bytes</span></code> is not
modified. If no bytes are available before an end-of-file, then
<code class=scheme><code class=scheme>eof</code></code> is returned. Otherwise, the return value is the number
of bytes read. If <code class=scheme><span class=variable>m</span></code> bytes are read and <code class=scheme><span class=variable>m</span></code> < <code class=scheme><span class=variable>end-k</span></code>
<tt>-</tt> <code class=scheme><span class=variable>start-k</span></code>, then <code class=scheme><span class=variable>bytes</span></code> is not modified at indices
<code class=scheme><span class=variable>start-k</span></code> + <code class=scheme><span class=variable>m</span></code> though <code class=scheme><span class=variable>end-k</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2018"></a><a name="node_kw_definitionread-bytes!"></a><code class=scheme>(read-bytes!</code><tt> </tt><code class=scheme><span class=variable>string</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port start-k end-k</span></code>]<code class=scheme>)</code> is
analogous to <code class=scheme>read-string!</code>, but it reads bytes and puts them
into a byte string.</p>
<p>
</p>
<li><p><a name="node_idx_2020"></a><a name="node_kw_definitionread-bytes-avail!"></a><code class=scheme>(read-bytes-avail!</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port start-k end-k</span></code>]<code class=scheme>)</code> is
like <code class=scheme>read-bytes!</code>, but returns without blocking after reading
immediately-available bytes, and it may return a procedure for a
``special'' result. The <code class=scheme><code class=scheme>read-bytes-avail!</code></code> procedure blocks
only if no bytes (or specials) are yet available. Also unlike
<code class=scheme>read-bytes!</code>, <code class=scheme><code class=scheme>read-bytes-avail!</code></code> never drops bytes;
if <code class=scheme><code class=scheme>read-bytes-avail!</code></code> successfully reads some bytes and then
encounters an error, it suppresses the error (treating it roughly
like an end-of-file) and returns the read bytes. (The error will be
triggered by future reads.) If an error is encountered before any
bytes have been read, an exception is raised.</p>
<p>
When <code class=scheme><span class=variable>input-port</span></code> produces a special value, as described in
section <a href="#node_sec_11.1.7">11.1.7</a>, the result is a procedure of four arguments. The
four arguments correspond to the location of the special value within
the port, as described in section <a href="#node_sec_11.1.7">11.1.7</a>. If the procedure is
called more than once with valid arguments, the
<a name="node_idx_2022"></a><code class=scheme>exn:fail:contract</code> exception is raised. If <code class=scheme><span class=variable>read-bytes-avail</span></code> returns a
special-producing procedure, then it does not place characters in
<code class=scheme><span class=variable>bytes</span></code>. Similarly, <code class=scheme><span class=variable>read-bytes-avail</span></code> places only as many
bytes into <code class=scheme><span class=variable>bytes</span></code> as are available before a special value in the
port's stream.</p>
<p>
</p>
<li><p><a name="node_idx_2024"></a><a name="node_kw_definitionread-bytes-avail!*"></a><code class=scheme>(read-bytes-avail!*</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port start-k end-k</span></code>]<code class=scheme>)</code> is
like <code class=scheme><code class=scheme>read-bytes-avail!</code></code>, except that it returns <code class=scheme><span class=selfeval>0</span></code>
immediately if no bytes (or specials) are available for reading and
the end-of-file is not reached.</p>
<p>
</p>
<li><p><a name="node_idx_2026"></a><a name="node_kw_definitionread-bytes-avail!/enable-break"></a><code class=scheme>(read-bytes-avail!/enable-break</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port
start-k end-k</span></code>]<code class=scheme>)</code> is like <code class=scheme><code class=scheme>read-bytes-avail!</code></code>, except that breaks
are enabled during the read (see also section <a href="mzscheme-Z-H-6.html#node_sec_6.6">6.6</a>). If
breaking is disabled when <code class=scheme><code class=scheme>read-bytes-avail!/enable-break</code></code> is
called, and if the <a name="node_idx_2028"></a><code class=scheme>exn:break</code> exception is raised as a result of
the call, then no bytes will have been read from <code class=scheme><span class=variable>input-port</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2030"></a><a name="node_kw_definitionpeek-string"></a><code class=scheme>(peek-string</code><tt> </tt><code class=scheme><span class=variable>k skip-k</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code> is similar to
<code class=scheme>read-string</code>, except that the returned characters are
preserved in the port for future reads. (More precisely, undecoded
bytes are left for future reads.) The <code class=scheme><span class=variable>skip-k</span></code> argument indicates
a number of bytes (<em>not</em> characters) in the input stream to skip
before collecting characters to return; thus, in total, the next
<code class=scheme><span class=variable>skip-k</span></code> bytes plus <code class=scheme><span class=variable>k</span></code> characters are inspected.</p>
<p>
For most kinds of ports, inspecting <code class=scheme><span class=variable>skip-k</span></code> bytes and <code class=scheme><span class=variable>k</span></code>
characters requires at least <code class=scheme><span class=variable>skip-k</span></code> + <code class=scheme><span class=variable>k</span></code> bytes of memory
overhead associated with the port, at least until the
bytes/characters are read. No such overhead is required when peeking
into a string port (see section <a href="#node_sec_11.1.5">11.1.5</a>), a pipe port (see
section <a href="#node_sec_11.1.4">11.1.4</a>), or a custom port with a specific peek procedure
(depending on how the peek procedure is implemented; see
section <a href="#node_sec_11.1.7">11.1.7</a>).</p>
<p>
If a port produces <code class=scheme><code class=scheme>eof</code></code> mid-stream, peek skips beyond the
<code class=scheme><code class=scheme>eof</code></code> always produce <code class=scheme><code class=scheme>eof</code></code> until the <code class=scheme><code class=scheme>eof</code></code> is
read.</p>
<p>
</p>
<li><p><a name="node_idx_2032"></a><a name="node_kw_definitionpeek-bytes"></a><code class=scheme>(peek-bytes</code><tt> </tt><code class=scheme><span class=variable>k skip-k</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code> is analogous to
<code class=scheme>peek-string</code>, but it peeks bytes and produces a byte string.</p>
<p>
</p>
<li><p><a name="node_idx_2034"></a><a name="node_kw_definitionpeek-string!"></a><code class=scheme>(peek-string!</code><tt> </tt><code class=scheme><span class=variable>string skip-k</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port start-k end-k</span></code>]<code class=scheme>)</code> is
like <code class=scheme>read-string!</code>, but for peeking, and with a <code class=scheme><span class=variable>skip-k</span></code>
argument like <code class=scheme><code class=scheme>peek-string</code></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2036"></a><a name="node_kw_definitionpeek-bytes!"></a><code class=scheme>(peek-bytes!</code><tt> </tt><code class=scheme><span class=variable>bytes skip-k</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port start-k end-k</span></code>]<code class=scheme>)</code> is
analogous to <code class=scheme>peek-string!</code>, but it peeks bytes and puts them
into a byte string.</p>
<p>
</p>
<li><p><a name="node_idx_2038"></a><a name="node_kw_definitionpeek-bytes-avail!"></a><code class=scheme>(peek-bytes-avail!</code><tt> </tt><code class=scheme><span class=variable>bytes skip-k</span></code><tt> </tt>[<code class=scheme><span class=variable>progress-evt input-port start-k end-k</span></code>]<code class=scheme>)</code>
is like <code class=scheme><code class=scheme>read-bytes-avail!</code></code>, but for peeking, and with two
extra arguments. The <code class=scheme><span class=variable>skip-k</span></code> argument is as in
<code class=scheme><code class=scheme>peek-bytes</code></code>. The <code class=scheme><span class=variable>progress-evt</span></code> argument must be either
<code class=scheme><span class=selfeval>#f</span></code> (the default) or an event produced by
<code class=scheme><code class=scheme>port-progress-evt</code></code> for <code class=scheme><span class=variable>input-port</span></code>.</p>
<p>
To peek, <code class=scheme><code class=scheme>peek-bytes-avail!</code></code> blocks until finding an
end-of-file, at least one byte (or special) past the skipped bytes,
or until a non-<code class=scheme><span class=selfeval>#f</span></code> <code class=scheme><span class=variable>progress-evt</span></code> becomes
ready. Furthermore, if <code class=scheme><span class=variable>progress-evt</span></code> is ready before bytes are
peeked, no bytes are peeked or skipped, and <code class=scheme><span class=variable>progress-evt</span></code> may
cut short the skipping process if it becomes available during the
peek attempt.</p>
<p>
The result of <code class=scheme><code class=scheme>peek-bytes-avail!</code></code> is <code class=scheme><span class=selfeval>0</span></code> only in the case
that <code class=scheme><span class=variable>progress-evt</span></code> becomes ready before bytes are peeked.</p>
<p>
</p>
<li><p><a name="node_idx_2040"></a><a name="node_kw_definitionpeek-bytes-avail!*"></a><code class=scheme>(peek-bytes-avail!*</code><tt> </tt><code class=scheme><span class=variable>bytes skip-k</span></code><tt> </tt>[<code class=scheme><span class=variable>progress-evt input-port start-k end-k</span></code>]<code class=scheme>)</code>
is like <code class=scheme><code class=scheme>read-bytes-avail!*</code></code>, but for peeking, and with
<code class=scheme><span class=variable>skip-k</span></code> and <code class=scheme><span class=variable>progress-evt</span></code> arguments like
<code class=scheme><code class=scheme>peek-bytes-avail!</code></code>. Since this procedure never blocks, it may
return before even <code class=scheme><span class=variable>skip-k</span></code> bytes are available from the port.</p>
<p>
</p>
<li><p><a name="node_idx_2042"></a><a name="node_kw_definitionpeek-bytes-avail!/enable-break"></a><code class=scheme>(peek-bytes-avail!/enable-break</code><tt> </tt><code class=scheme><span class=variable>bytes skip-k</span></code><tt> </tt>[<code class=scheme><span class=variable>progress-evt input-port start-k end-k</span></code>]<code class=scheme>)</code>
is the peeking version of <code class=scheme><code class=scheme>read-bytes-avail!/enable-break</code></code>,
with <code class=scheme><span class=variable>skip-k</span></code> and <code class=scheme><span class=variable>progress-evt</span></code> arguments like
<code class=scheme><code class=scheme>peek-bytes-avail!</code></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2044"></a><a name="node_kw_definitionread-byte"></a><code class=scheme>(read-byte</code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code> is analogous to <code class=scheme><code class=scheme>read-char</code></code>,
but it reads and returns a byte (or <code class=scheme>eof</code>) instead of a
character.</p>
<p>
</p>
<li><p><a name="node_idx_2046"></a><a name="node_kw_definitionread-char-or-special"></a><code class=scheme>(read-char-or-special</code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code> is the same as
<code class=scheme><code class=scheme>read-char</code></code>, except that if the input port returns a non-byte
value (through a value-generating procedure in a custom port; see
section <a href="#node_sec_11.1.7">11.1.7</a> and section <a href="#node_sec_11.2.9.1">11.2.9.1</a> for details), the
non-byte value is returned.</p>
<p>
</p>
<li><p><a name="node_idx_2048"></a><a name="node_kw_definitionread-byte-or-special"></a><code class=scheme>(read-byte-or-special</code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code> is analogous to
<code class=scheme><code class=scheme>read-char-or-special</code></code>, but it reads and returns a byte
instead of a character.</p>
<p>
</p>
<li><p><a name="node_idx_2050"></a><a name="node_kw_definitionpeek-char"></a><code class=scheme>(peek-char</code><tt> </tt>[<code class=scheme><span class=variable>input-port skip-k</span></code>]<code class=scheme>)</code> extends the standard
<code class=scheme><code class=scheme>peek-char</code></code> with an optional argument (defaulting to <code class=scheme><span class=selfeval>0</span></code>)
that represents the number of bytes (not characters) to skip.</p>
<p>
</p>
<li><p><a name="node_idx_2052"></a><a name="node_kw_definitionpeek-byte"></a><code class=scheme>(peek-byte</code><tt> </tt>[<code class=scheme><span class=variable>input-port skip-k</span></code>]<code class=scheme>)</code> is analogous to
<code class=scheme><code class=scheme>peek-char</code></code>, but it reads and returns a byte instead of a
character.</p>
<p>
</p>
<li><p><a name="node_idx_2054"></a><a name="node_kw_definitionpeek-char-or-special"></a><code class=scheme>(peek-char-or-special</code><tt> </tt>[<code class=scheme><span class=variable>input-port skip-k</span></code>]<code class=scheme>)</code> is the same as
<code class=scheme><code class=scheme>peek-char</code></code>, except that if the input port returns a non-byte
value after <code class=scheme><span class=variable>skip-k</span></code> byte positions, it is returned.</p>
<p>
</p>
<li><p><a name="node_idx_2056"></a><a name="node_kw_definitionpeek-byte-or-special"></a><code class=scheme>(peek-byte-or-special</code><tt> </tt>[<code class=scheme><span class=variable>input-port skip-k progress-evt</span></code>]<code class=scheme>)</code> is
analogous to <code class=scheme><code class=scheme>peek-char-or-special</code></code>, but it reads and returns
a byte instead of a character, and it supports a <code class=scheme><span class=variable>progress-evt</span></code>
argument (which is <code class=scheme><span class=selfeval>#f</span></code> by default) like
<code class=scheme><code class=scheme>peek-bytes-avail!</code></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2058"></a><a name="node_kw_definitionport-progress-evt"></a><code class=scheme>(port-progress-evt</code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code> returns an event that
becomes ready after any subsequent read from <code class=scheme><span class=variable>input-port</span></code>, or
after <code class=scheme><span class=variable>input-port</span></code> is closed. After the event becomes ready, it
remains ready. If progress events are unavailable for
<code class=scheme><span class=variable>input-port</span></code> (as reported by
<code class=scheme>port-provides-progress-evts?</code>) the
<a name="node_idx_2060"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2062"></a><a name="node_kw_definitionport-provides-progress-evts_Q_"></a><code class=scheme>(port-provides-progress-evts?</code><tt> </tt><code class=scheme><span class=variable>input-port</span></code><code class=scheme>)</code> returns
<code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme>port-progress-evt</code> can return an event for
<code class=scheme><span class=variable>input-port</span></code>. All built-in kinds of ports support progress
events, but ports created with <code class=scheme>make-input-port</code> (see
section <a href="#node_sec_11.1.7">11.1.7</a>) may not.</p>
<p>
</p>
<li><p><a name="node_idx_2064"></a><a name="node_kw_definitionport-commit-peeked"></a><code class=scheme>(port-commit-peeked</code><tt> </tt><code class=scheme><span class=variable>k progress-evt evt</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port</span></code>]<code class=scheme>)</code>
attempts to commit as read the first <code class=scheme><span class=variable>k</span></code> previously peeked bytes,
non-byte specials, and <code class=scheme><code class=scheme>eof</code></code>s from <code class=scheme><span class=variable>input-port</span></code>, or the
first <code class=scheme><code class=scheme>eof</code></code> or special value peeked
from <code class=scheme><span class=variable>input-port</span></code>.<a name="node_call_footnote_32"></a><a href="#node_footnote_32"><sup><small>32</small></sup></a> The read commits only
if <code class=scheme><span class=variable>progress-evt</span></code> does not become ready first (i.e., if no other
process reads from <code class=scheme><span class=variable>input-port</span></code> first), and only if <code class=scheme><span class=variable>evt</span></code> is
chosen by a <code class=scheme><code class=scheme>sync</code></code> within <code class=scheme>port-commit-peeked</code> (in
which case the event result is ignored); the <code class=scheme><span class=variable>evt</span></code> must be either
a channel-put event, channel, semaphore, semaphore-peek event, always
event, or never event. Suspending the thread that
calls <code class=scheme>port-commit-peeked</code> may or may not prevent the commit
from proceeding. The result from <code class=scheme>port-commit-peeked</code>
is <code class=scheme><span class=selfeval>#t</span></code> if data is committed, and <code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
If no data has been peeked from <code class=scheme><span class=variable>input-port</span></code> and
<code class=scheme><span class=variable>progress-evt</span></code> is not ready, then <a name="node_idx_2066"></a><code class=scheme>exn:fail:contract</code> exception is raised.
If fewer than <code class=scheme><span class=variable>k</span></code> items have been peeked at the current start of
<code class=scheme><span class=variable>input-port</span></code>'s stream, then only the peeked items are committed
as read. If <code class=scheme><span class=variable>input-port</span></code>'s stream currently starts at an
<code class=scheme><code class=scheme>eof</code></code> or a non-byte special value, then only the <code class=scheme><code class=scheme>eof</code></code>
or special value is committed as read.</p>
<p>
If <code class=scheme><span class=variable>progress-evt</span></code> is not a result of <code class=scheme>port-progress-evt</code>
applied to <code class=scheme><span class=variable>input-port</span></code>, then <a name="node_idx_2068"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.2.1.1"></a>
<h4><a href="mzscheme.html#node_toc_node_sec_11.2.1.1">11.2.1.1 Counting Positions, Lines, and Columns</a></h4>
<p></p>
<p>
<a name="node_idx_2070"></a> <a name="node_idx_2072"></a> <a name="node_idx_2074"></a>
By default, MzScheme keeps track of the <strong>position</strong> in a port
as the number of bytes that have been read from or written to any
port (independent of the read/write position, which is accessed or
changed with <code class=scheme><code class=scheme>file-position</code></code>). Optionally, however, MzScheme
can track the position in terms of characters (after UTF-8 decoding),
instead of bytes, and it can track <strong>line locations</strong> and
<strong>column locations</strong>; this optional tracking must be
specifically enabled for a port via <code class=scheme><code class=scheme>port-count-lines!</code></code> or
the <code class=scheme><code class=scheme>port-count-lines-enabled</code></code> parameter (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.2">7.9.1.2</a>). Position, line, and column
locations for a port are used by <code class=scheme><code class=scheme>read-syntax</code></code> (see
section <a href="mzscheme-Z-H-12.html#node_sec_12.2">12.2</a> for more information) and
<code class=scheme>read-honu-syntax</code>. Position and line locations are numbered
from 1; column locations are numbered from 0.
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2076"></a><a name="node_kw_definitionport-count-lines!"></a><code class=scheme>(port-count-lines!</code><tt> </tt><code class=scheme><span class=variable>port</span></code><code class=scheme>)</code> turns on line and column counting
for a port. Counting can be turned on at any time, though generally
it is turned on before any data is read from or written to a
port. When a port is created, if the value of the
<code class=scheme>port-count-lines-enabled</code> parameter is true (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.2">7.9.1.2</a>), then line counting is
automatically enabled for the port. Line counting cannot be disabled
for a port after it is enabled.</p>
<p>
</p>
</ul><p>
When counting lines, MzScheme treats linefeed, return, and
return-linefeed combinations as a line terminator and as a single
position (on all platforms). Each tab advances the column count to
one before the next multiple of 8. When a sequence of bytes in the
range 128 to 253 forms a UTF-8 encoding of a character, the
position/column is incremented is incremented once for each byte, and
then decremented appropriately when a complete encoding sequence is
discovered. See also section <a href="#node_sec_11.1">11.1</a> for more information on UTF-8
decoding for ports.</p>
<p>
A position is known for any port as long as its value can be expressed
as a fixnum (which is more than enough tracking for realistic
applications in, say, syntax-error reporting). If the position for a
port exceeds the value of the largest fixnum, then the position for
the port becomes unknown, and line and column tacking is disabled.
Return-linefeed combinations are treated as a single character
position only when line and column counting is enabled.
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2078"></a><a name="node_kw_definitionport-next-location"></a><code class=scheme>(port-next-location</code><tt> </tt><code class=scheme><span class=variable>port</span></code><code class=scheme>)</code> returns three values: a positive
exact integer or <code class=scheme><span class=selfeval>#f</span></code> for the line number of the next
read/written item, a non-negative exact integer or <code class=scheme><span class=selfeval>#f</span></code> for
the next item's column, and a positive exact integer or <code class=scheme><span class=selfeval>#f</span></code>
for the next item's position. The next column and position normally
increases as bytes are read from or written to the port, but if
line/character counting is enabled for <code class=scheme><span class=variable>port</span></code>, the column and
position results can decrease after reading or writing a byte that
ends a UTF-8 encoding sequence.</p>
<p>
</p>
</ul><p></p>
<p>
Certain kinds of exceptions (see section <a href="mzscheme-Z-H-6.html#node_sec_6.1">6.1</a>) encapsulate
source-location information using a <a name="node_kw_definitionsrcloc"></a><a name="node_idx_2080"></a><code class=scheme><span class=keyword>srcloc</span></code> structure, which
has five fields: <a name="node_kw_definitionstruct_C_srcloc"></a>
<a name="node_kw_definitionmake-srcloc"></a> <a name="node_kw_definitionsrcloc_Q_"></a>
<a name="node_kw_definitionsrcloc-source"></a> <a name="node_kw_definitionsrcloc-line"></a>
<a name="node_kw_definitionsrcloc-column"></a> <a name="node_kw_definitionsrcloc-position"></a>
<a name="node_kw_definitionsrcloc-span"></a>
</p>
<ul><p>
</p>
<li><p><code class=scheme>source</code> -- An arbitrary value identifying the source,
often a path (see section <a href="#node_sec_11.3.1">11.3.1</a>).</p>
<p>
</p>
<li><p><code class=scheme>line</code> -- The line number, a positive exact integer
(counts from 1) or <code class=scheme><span class=selfeval>#f</span></code> (unknown).</p>
<p>
</p>
<li><p><code class=scheme>column</code> -- The column number, a non-negative exact
integer (counts from 0) or <code class=scheme><span class=selfeval>#f</span></code> (unknown).</p>
<p>
</p>
<li><p><code class=scheme>position</code> -- The starting position, a positive exact
integer (counts from 1) or <code class=scheme><span class=selfeval>#f</span></code> (unknown).</p>
<p>
</p>
<li><p><code class=scheme>span</code> -- The number of covered positions, a
non-negative exact integer (counts from 0) or <code class=scheme><span class=selfeval>#f</span></code> (unknown).</p>
<p>
</p>
</ul><p>
The fields of a <code class=scheme>srcloc</code> structure are immutable, so no
field-mutator procedures are defined for <code class=scheme>srcloc</code>. The
<code class=scheme>srcloc</code> structure type is transparent to all inspectors (see
section <a href="mzscheme-Z-H-4.html#node_sec_4.5">4.5</a>).</p>
<p>
</p>
<a name="node_sec_11.2.2"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.2">11.2.2 Writing Bytes, Characters, and Strings</a></h3>
<p></p>
<p>
In addition to the standard printing procedures, MzScheme provides
byte-writing procedures, block-writing procedures such as
<code class=scheme>write-string</code>, and more.
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2082"></a><a name="node_kw_definitionwrite-string"></a><code class=scheme>(write-string</code><tt> </tt><code class=scheme><span class=variable>string</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port start-k end-k</span></code>]<code class=scheme>)</code>
write characters to <code class=scheme><span class=variable>output-port</span></code> from <code class=scheme><span class=variable>string</span></code> starting from
index <code class=scheme><span class=variable>start-k</span></code> (inclusive) up to <code class=scheme><span class=variable>end-k</span></code> (exclusive). The
default value of <code class=scheme><span class=variable>output-port</span></code> is the current output port. The
default value of <code class=scheme><span class=variable>start-k</span></code> is <code class=scheme><span class=selfeval>0</span></code>. The default value of
<code class=scheme><span class=variable>end-k</span></code> is the length of the <code class=scheme><span class=variable>string</span></code>. Like <code class=scheme><code class=scheme>substring</code></code>,
the <a name="node_idx_2084"></a><code class=scheme>exn:fail:contract</code> exception is raised if <code class=scheme><span class=variable>start-k</span></code> or
<code class=scheme><span class=variable>end-k</span></code> is out-of-range for <code class=scheme><span class=variable>string</span></code>.</p>
<p>
The result is the number of characters written to <code class=scheme><span class=variable>output-port</span></code>,
which is always <code class=scheme>(<span class=variable>-</span> <span class=variable>end-k</span> <span class=variable>start-k</span>)</code>.</p>
<p>
</p>
<li><p><a name="node_idx_2086"></a><a name="node_kw_definitionwrite-bytes"></a><code class=scheme>(write-bytes</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port start-k end-k</span></code>]<code class=scheme>)</code> is
analogous to <code class=scheme><span class=variable>write-string</span></code>, but it writes a byte string.</p>
<p>
</p>
<li><p><a name="node_idx_2088"></a><a name="node_kw_definitionwrite-bytes-avail"></a><code class=scheme>(write-bytes-avail</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port start-k end-k</span></code>]<code class=scheme>)</code> is
like <code class=scheme>write-bytes</code>, but it returns without blocking after
writing as many bytes as it can immediately flush. It blocks only if
no bytes can be flushed immediately. The result is the number of
bytes written and flushed to <code class=scheme><span class=variable>output-port</span></code>; if <code class=scheme><span class=variable>start-k</span></code>
is the same as <code class=scheme><span class=variable>end-k</span></code>, then the result can be <code class=scheme><span class=selfeval>0</span></code>
(indicating a successful flush of any buffered data), otherwise the
result is at least <code class=scheme><span class=selfeval>1</span></code> but possibly less than <code class=scheme>(<span class=variable>-</span> <span class=variable>end-k</span>
<span class=variable>start-k</span>)</code>.</p>
<p>
The <code class=scheme><span class=variable>write-bytes-avail</span></code> procedure never drops bytes; if
<code class=scheme><span class=variable>write-bytes-avail</span></code> successfully writes some bytes and then
encounters an error, it suppresses the error and returns the number
of written bytes. (The error will be triggered by future
writes.) If an error is encountered before any bytes have been
written, an exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2090"></a><a name="node_kw_definitionwrite-bytes-avail*"></a><code class=scheme>(write-bytes-avail*</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port start-k end-k</span></code>]<code class=scheme>)</code> is
like <code class=scheme><span class=variable>write-bytes-avail</span></code>, except that it never blocks, it
returns <code class=scheme><span class=selfeval>#f</span></code> if the port contains buffered data that cannot be
written immediately, and it returns <code class=scheme><span class=selfeval>0</span></code> if the port's internal
buffer (if any) is flushed but no additional bytes can be
written immediately.</p>
<p>
</p>
<li><p><a name="node_idx_2092"></a><a name="node_kw_definitionwrite-bytes-avail/enable-break"></a><code class=scheme>(write-bytes-avail/enable-break</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>input-port
start-k end-k</span></code>]<code class=scheme>)</code> is like <code class=scheme><span class=variable>write-bytes-avail</span></code>, except that
breaks are enabled during the write. The procedure provides a
guarantee about the interaction of writing and breaks: if breaking is
disabled when <code class=scheme><span class=variable>write-bytes-avail/enable-break</span></code> is called, and
if the <a name="node_idx_2094"></a><code class=scheme>exn:break</code> exception is raised as a result of the
call, then no bytes will have been written to <code class=scheme><span class=variable>output-port</span></code>.
See also section <a href="mzscheme-Z-H-6.html#node_sec_6.6">6.6</a>.</p>
<p>
</p>
<li><p><a name="node_idx_2096"></a><a name="node_kw_definitionwrite-byte"></a><code class=scheme>(write-byte</code><tt> </tt><code class=scheme><span class=variable>byte</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port</span></code>]<code class=scheme>)</code> is analogous to
<code class=scheme>write-char</code>, but for writing a byte instead of a character.</p>
<p>
</p>
<li><p><a name="node_idx_2098"></a><a name="node_kw_definitionwrite-special"></a><code class=scheme>(write-special</code><tt> </tt><code class=scheme><span class=variable>v</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port</span></code>]<code class=scheme>)</code> writes <code class=scheme><span class=variable>v</span></code> directly to
<code class=scheme><span class=variable>output-port</span></code> if it supports special writes, or raises
<a name="node_idx_2100"></a><code class=scheme>exn:fail:contract</code> if the port does not support special
write. The result is always <code class=scheme><span class=selfeval>#t</span></code>, indicating that the write
succeeded.</p>
<p>
</p>
<li><p><a name="node_idx_2102"></a><a name="node_kw_definitionwrite-special-avail*"></a><code class=scheme>(write-special-avail*</code><tt> </tt><code class=scheme><span class=variable>v</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port</span></code>]<code class=scheme>)</code> is like
<code class=scheme>write-special</code>, but without blocking. If <code class=scheme><span class=variable>v</span></code> cannot be
written immediately, the result is <code class=scheme><span class=selfeval>#f</span></code> without writing
<code class=scheme><span class=variable>v</span></code>, otherwise the result is <code class=scheme><span class=selfeval>#t</span></code> and <code class=scheme><span class=variable>v</span></code> is written.</p>
<p>
</p>
<li><p><a name="node_idx_2104"></a><a name="node_kw_definitionwrite-bytes-avail-evt"></a><code class=scheme>(write-bytes-avail-evt</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port start-k end-k</span></code>]<code class=scheme>)</code>
is similar to <code class=scheme>write-bytes-avail</code>, but instead of writing
bytes immediately, it returns a synchronizable event
(see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>). The <code class=scheme><span class=variable>output-port</span></code> must support atomic
writes, as indicated by <code class=scheme>port-writes-atomic?</code>.</p>
<p>
Synchronizing on the object starts a write from <code class=scheme><span class=variable>bytes</span></code>, and the
event becomes ready when bytes are written (unbuffered) to the
port. If <code class=scheme><span class=variable>start-k</span></code> and <code class=scheme><span class=variable>end-k</span></code> are the same, then the
synchronization result is <code class=scheme><span class=selfeval>0</span></code> when the port's internal buffer
(if any) is flushed, otherwise the result is a positive exact
integer. If the event is not selected in a synchronization, then
no bytes will have been written to <code class=scheme><span class=variable>output-port</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2106"></a><a name="node_kw_definitionwrite-special-evt"></a><code class=scheme>(write-special-evt</code><tt> </tt><code class=scheme><span class=variable>v</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port</span></code>]<code class=scheme>)</code> is similar
to <code class=scheme>write-special</code>, but instead of writing the special value
immediately, it returns a synchronizable event (see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>).
The <code class=scheme><span class=variable>output-port</span></code> must support atomic writes, as indicated
by <code class=scheme>port-writes-atomic?</code>.</p>
<p>
Synchronizing on the object starts a write of the special value, and
the event becomes ready when the value is written (unbuffered) to
the port. If the event is not selected in a synchronization, then
no value will have been written to <code class=scheme><span class=variable>output-port</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2108"></a><a name="node_kw_definitionport-writes-atomic_Q_"></a><code class=scheme>(port-writes-atomic?</code><tt> </tt><code class=scheme><span class=variable>output-port</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code>
if <code class=scheme>write-bytes-avail/enable-break</code> can provide an
exclusive-or guarantee (break or write, but not both)
for <code class=scheme><span class=variable>output-port</span></code>, and if the port can be used with procedures
like <code class=scheme>write-bytes-avail-evt</code>. MzScheme's file-stream ports,
pipes, string ports, and TCP ports all support atomic writes; ports
created with <code class=scheme>make-output-port</code> (see section <a href="#node_sec_11.1.7">11.1.7</a>)
may support atomic writes.</p>
<p>
</p>
<li><p><a name="node_idx_2110"></a><a name="node_kw_definitionport-writes-special_Q_"></a><code class=scheme>(port-writes-special?</code><tt> </tt><code class=scheme><span class=variable>output-port</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if
procedures like <code class=scheme>write-special</code> can write arbitrary values to
the port. MzScheme's file-stream ports, pipes, string ports, and TCP
ports all reject special values, but ports created
with <code class=scheme>make-output-port</code> (see section <a href="#node_sec_11.1.7">11.1.7</a>) may
support them.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.2.3"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.3">11.2.3 Writing Structured Data</a></h3>
<p></p>
<p>
The <code class=scheme><code class=scheme>print</code></code> procedure is used to print Scheme values in a
context where a programmer expects to see a value:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2112"></a><a name="node_kw_definitionprint"></a><code class=scheme>(print</code><tt> </tt><code class=scheme><span class=variable>v</span></code><tt> </tt>[<code class=scheme><span class=variable>output-port</span></code>]<code class=scheme>)</code> outputs <code class=scheme><span class=variable>v</span></code> to
<code class=scheme><span class=variable>output-port</span></code>. The default value of <code class=scheme><span class=variable>output-port</span></code> is the
current output port.</p>
<p>
</p>
</ul><p>
The rationale for providing <code class=scheme><code class=scheme>print</code></code> is that <code class=scheme><code class=scheme>display</code></code>
and <code class=scheme><code class=scheme>write</code></code> both have standard output conventions, and this
standardization restricts the ways that an environment can change the
behavior of these procedures. No output conventions should be assumed
for <code class=scheme><code class=scheme>print</code></code> so that environments are free to modify the actual
output generated by <code class=scheme><code class=scheme>print</code></code> in any way. Unlike the port
display and write handlers, a global port print handler can be
installed through the <a name="node_idx_2114"></a><code class=scheme>global-port-print-handler</code> parameter
(see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.2">7.9.1.2</a>).</p>
<p>
The <code class=scheme><code class=scheme>fprintf</code></code>, <code class=scheme><code class=scheme>printf</code></code>, and <code class=scheme><code class=scheme>format</code></code> procedures
create formatted output:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2116"></a><a name="node_kw_definitionfprintf"></a><code class=scheme>(fprintf</code><tt> </tt><code class=scheme><span class=variable>output-port format-string v</span></code><tt> </tt><tt>···</tt><code class=scheme>)</code> prints formatted
output to <code class=scheme><span class=variable>output-port</span></code>, where <code class=scheme><span class=variable>format-string</span></code> is a string
that is printed; <code class=scheme><span class=variable>format-string</span></code> can contain special formatting
tags:
</p>
<ul><p>
</p>
<li><p><code class=scheme>~</code>n or <code class=scheme>~</code>% prints a newline</p>
<p>
</p>
<li><p><code class=scheme>~</code>a or <code class=scheme>~</code>A <code class=scheme><code class=scheme>display</code></code>s the next argument
among the <code class=scheme><span class=variable>v</span></code>s</p>
<p>
</p>
<li><p><code class=scheme>~</code>s or <code class=scheme>~</code>S <code class=scheme><code class=scheme>write</code></code>s the next argument
among the <code class=scheme><span class=variable>v</span></code>s</p>
<p>
</p>
<li><p><code class=scheme>~</code>v or <code class=scheme>~</code>V <code class=scheme><code class=scheme>print</code></code>s the next argument
among the <code class=scheme><span class=variable>v</span></code>s</p>
<p>
</p>
<li><p><code class=scheme>~</code>e or <code class=scheme>~</code>E outputs the next argument among the
<code class=scheme><span class=variable>v</span></code>s using the current error value conversion handler (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.7">7.9.1.7</a>) and current error printing
width </p>
<li><p><code class=scheme>~</code>c or <code class=scheme>~</code>C <code class=scheme><code class=scheme>write-char</code></code>s the next
argument in <code class=scheme><span class=variable>v</span></code>s; if the next argument is not a character, the
<a name="node_idx_2118"></a><code class=scheme>exn:fail:contract</code> exception is raised</p>
<p>
</p>
<li><p><code class=scheme>~</code>b or <code class=scheme>~</code>B prints the next argument among the
<code class=scheme><span class=variable>v</span></code>s in binary; if the next argument is not an exact number, the
<a name="node_idx_2120"></a><code class=scheme>exn:fail:contract</code> exception is raised</p>
<p>
</p>
<li><p><code class=scheme>~</code>o or <code class=scheme>~</code>O prints the next argument among the
<code class=scheme><span class=variable>v</span></code>s in octal; if the next argument is not an exact number, the
<a name="node_idx_2122"></a><code class=scheme>exn:fail:contract</code> exception is raised</p>
<p>
</p>
<li><p><code class=scheme>~</code>x or <code class=scheme>~</code>X prints the next argument among the
<code class=scheme><span class=variable>v</span></code>s in hexadecimal; if the next argument is not an exact
number, the <a name="node_idx_2124"></a><code class=scheme>exn:fail:contract</code> exception is raised</p>
<p>
</p>
<li><p><code class=scheme>~</code>~ prints a tilde (~)</p>
<p>
</p>
<li><p><code class=scheme>~</code><code class=scheme><span class=variable>w</span></code>, where <code class=scheme><span class=variable>w</span></code> is a whitespace character,
skips characters in <code class=scheme><span class=variable>format-string</span></code> until a non-whitespace
character is encountered or until a second end-of-line is
encountered (whichever happens first). An end-of-line is either
<code class=scheme><span class=selfeval>#\return</span></code>, <code class=scheme><span class=selfeval>#\newline</span></code>, or <code class=scheme><span class=selfeval>#\return</span></code> followed
immediately by <code class=scheme><span class=selfeval>#\newline</span></code> (on all platforms).</p>
<p>
</p>
</ul><p>
The return value is void.</p>
<p>
</p>
<li><p><a name="node_idx_2126"></a><a name="node_kw_definitionprintf"></a><code class=scheme>(printf</code><tt> </tt><code class=scheme><span class=variable>format-string v</span></code><tt> </tt><tt>···</tt><code class=scheme>)</code> same as <code class=scheme><code class=scheme>fprintf</code></code> with the
current output port.</p>
<p>
</p>
<li><p><a name="node_idx_2128"></a><a name="node_kw_definitionformat"></a><code class=scheme>(format</code><tt> </tt><code class=scheme><span class=variable>format-string v</span></code><tt> </tt><tt>···</tt><code class=scheme>)</code> same as <code class=scheme><code class=scheme>fprintf</code></code> with a
string output port where the final string is returned as the result.</p>
<p>
</p>
</ul><p></p>
<p>
When an illegal format string is supplied to one of these procedures,
the <a name="node_idx_2130"></a><code class=scheme>exn:fail:contract</code> exception is raised. When the format string requires more
additional arguments than are supplied, the
<a name="node_idx_2132"></a><code class=scheme>exn:fail:contract</code> exception is raised. When more additional arguments are supplied
than are used by the format string, the <a name="node_idx_2134"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
For example,
</p>
<div align=left><pre class=scheme>(<code class=scheme>fprintf</code> <span class=variable>port</span> <span class=selfeval>"~a as a string is ~s.~n"</span> <span class=keyword>'</span>(<span class=selfeval>3</span> <span class=selfeval>4</span>) <span class=selfeval>"(3 4)"</span>)
</pre></div><p>
prints this message to <code class=scheme><span class=variable>port</span></code>:<a name="node_call_footnote_33"></a><a href="#node_footnote_33"><sup><small>33</small></sup></a>
</p>
<div align=left><pre class=schemeresponse>(<span class=selfeval>3</span> <span class=selfeval>4</span>) <span class=variable>as</span> <span class=variable>a</span> <span class=variable>string</span> <span class=variable>is</span> <span class=selfeval>"(3 4)"</span>.
</pre></div><p>
followed by a newline.</p>
<p>
</p>
<a name="node_sec_11.2.4"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.4">11.2.4 Default Reader</a></h3>
<p></p>
<p>
<a name="node_idx_2136"></a>
MzScheme's input parser obeys the following non-standard rules. See
also section <a href="#node_sec_11.2.8">11.2.8</a> for information on configuring the input
parser through a readtable.
</p>
<ul><p>
</p>
<li><p>Square brackets (``['' and ``]'') and curly braces
(``{'' and ``}'') can be used in place of parentheses. An open
square bracket must be closed by a closing square bracket and an open
curly brace must be closed by a closing curly brace. Whether square
brackets are treated as parentheses is controlled by the
<a name="node_idx_2138"></a><code class=scheme>read-square-bracket-as-paren</code> parameter (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.3">7.9.1.3</a>). Similarly, the parsing of
curly braces is controlled with the
<a name="node_idx_2140"></a><code class=scheme>read-curly-brace-as-paren</code> parameter. When square brackets
and curly braces are not treated as parentheses, they are disallowed
as input. By default, square brackets and curly braces are treated as
parentheses.</p>
<p>
<a name="node_idx_2142"></a>
</p>
<li><p>Vector constants can be unquoted, and a vector size can
be specified with a decimal integer between the <code class=scheme><span class=selfeval>#</span></code> and opening
parenthesis. If the specified size is larger than the number of
vector elements that are provided, the last specified element is used
to fill the remaining vector slots. For example, <code class=scheme><span class=selfeval>#4</span>(<span class=selfeval>1</span> <span class=selfeval>2</span>)</code> is
equivalent to <code class=scheme><span class=selfeval>#</span>(<span class=selfeval>1</span> <span class=selfeval>2</span> <span class=selfeval>2</span> <span class=selfeval>2</span>)</code>. If no vector elements are specified,
the vector is filled with <code class=scheme><span class=selfeval>0</span></code>. If a vector size is provided and
it is smaller than the number of elements provided, the
<a name="node_idx_2144"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
<a name="node_idx_2146"></a> <a name="node_idx_2148"></a>
</p>
<li><p>Boxed constants can be created using <code class=scheme><span class=selfeval>#&</span></code>. The datum
following <code class=scheme><span class=selfeval>#&</span></code> is treated as a quoted constant and put into
the new box. (Space and comments following the <code class=scheme><span class=selfeval>#&</span></code> are
ignored.) Box reading is controlled with the
<a name="node_idx_2150"></a><code class=scheme>read-accept-box</code> boolean parameter (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.3">7.9.1.3</a>). Box reading is enabled by default. When
box reading is disabled and <code class=scheme><span class=selfeval>#&</span></code> is provided as input, the
<a name="node_idx_2152"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
<a name="node_idx_2154"></a><a name="node_idx_2156"></a><a name="node_idx_2158"></a><a name="node_idx_2160"></a>
</p>
<li><p>Expressions beginning with <code class=scheme><span class=selfeval>#</span><span class=keyword>'</span></code> are wrapped with <code class=scheme><span class=keyword>syntax</span></code>
in the same way that expressions starting with <code class=scheme><span class=keyword>'</span></code> are wrapped
with <code class=scheme><span class=keyword>quote</span></code>. Similarly, <code class=scheme><span class=selfeval>#</span><span class=keyword>`</span></code> generates
<code class=scheme><span class=keyword>quasisyntax</span></code>, <code class=scheme><span class=selfeval>#</span><span class=keyword>,</span></code> generates <code class=scheme><span class=keyword>unsyntax</span></code>, and
<code class=scheme><span class=selfeval>#</span><span class=keyword>,@</span></code> generates <code class=scheme><span class=keyword>unsyntax-splicing</span></code>. See also
section <a href="mzscheme-Z-H-12.html#node_sec_12.2.1.2">12.2.1.2</a>.</p>
<p>
<a name="node_idx_2162"></a>
</p>
<li><p>The following character constants are recognized:
</p>
<ul>
<li><p><code class=scheme><span class=selfeval>#\nul</span></code> or <code class=scheme><span class=selfeval>#\null</span></code> (ASCII 0) <a name="node_idx_2164"></a> <a name="node_idx_2166"></a>
</p>
<li><p><code class=scheme><span class=selfeval>#\backspace</span></code> (ASCII 8) <a name="node_idx_2168"></a>
</p>
<li><p><code class=scheme><span class=selfeval>#\tab</span></code> (ASCII 9) <a name="node_idx_2170"></a>
</p>
<li><p><code class=scheme><span class=selfeval>#\newline</span></code> or <code class=scheme><span class=selfeval>#\linefeed</span></code> (ASCII 10) <a name="node_idx_2172"></a><a name="node_idx_2174"></a>
</p>
<li><p><code class=scheme><span class=selfeval>#\vtab</span></code> (ASCII 11) <a name="node_idx_2176"></a>
</p>
<li><p><code class=scheme><span class=selfeval>#\page</span></code> (ASCII 12) <a name="node_idx_2178"></a>
</p>
<li><p><code class=scheme><span class=selfeval>#\return</span></code> (ASCII 13) <a name="node_idx_2180"></a>
</p>
<li><p><code class=scheme><span class=selfeval>#\space</span></code> (ASCII 32) <a name="node_idx_2182"></a>
</p>
<li><p><code class=scheme><span class=selfeval>#\rubout</span></code> (ASCII 127) <a name="node_idx_2184"></a>
</p>
</ul><p>
Whenever <code class=scheme><span class=selfeval>#\ </span></code> is followed by at least two alphabetic characters,
characters are read from the input port until the next non-alphabetic
character is returned. If the resulting string of letters does not
match one of the above constants (case-insensitively), the
<a name="node_idx_2186"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
Character constants can also be specified through direct Unicode values
in octal notation (up to 255): <code class=scheme>#<tt>\</tt><code class=scheme><span class=variable>n<sub>1</sub></span></code><code class=scheme><span class=variable>n<sub>2</sub></span></code><code class=scheme><span class=variable>n<sub>3</sub></span></code></code> where
<code class=scheme><span class=variable>n<sub>1</sub></span></code> is in the range [<code class=scheme><span class=selfeval>0</span></code>, <code class=scheme><span class=selfeval>3</span></code>] and <code class=scheme><span class=variable>n<sub>2</sub></span></code> and
<code class=scheme><span class=variable>n<sub>3</sub></span></code> are in the range [<code class=scheme><span class=selfeval>0</span></code>, <code class=scheme><span class=selfeval>7</span></code>]. Whenever <code class=scheme><span class=selfeval>#\ </span></code> is
followed by at least two characters in the range [<code class=scheme><span class=selfeval>0</span></code>, <code class=scheme><span class=selfeval>7</span></code>],
the next character must also be in this range, and the resulting octal
number must be in the range 000<sub>8</sub> to 377<sub>8</sub>.</p>
<p>
Finally, character constants can be specified through direct Unicode
values in hexadecimal notation:
<code class=scheme>#<tt>\</tt>u<code class=scheme><span class=variable>n<sub>1</sub></span></code>...<code class=scheme><span class=variable>n<sub><em>k</em></sub></span></code></code>
or <code class=scheme>#<tt>\</tt>U<code class=scheme><span class=variable>n<sub>1</sub></span></code>...<code class=scheme><span class=variable>n<sub><em>k</em></sub></span></code></code>, where each
<code class=scheme><span class=variable>n<sub><em>i</em></sub></span></code> is a hexadecimal digit (0-9, a-f, or A-F), and <em>k</em> is no
more than 4 for <code class=scheme>#<tt>\</tt>u</code> or 6 for <code class=scheme>#<tt>\</tt>U</code>.
Whenever <code class=scheme><span class=selfeval>#\ </span></code> is followed by a <code class=scheme><span class=variable>u</span></code> or <code class=scheme><span class=variable>U</span></code> and
one hexadecimal digit, the character constant is terminated by either
the first non-hexadecimal character in the stream, or the fourth/sixth
hexadecimal character, whichever comes first. The resulting
hexadecimal number must be a valid argument to
<code class=scheme>integer->char</code>, otherwise the <a name="node_idx_2188"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
Unless otherwise specified above, character-constants are terminated
after the character following <code class=scheme><span class=selfeval>#\ </span></code>. For example, if
<code class=scheme><span class=selfeval>#\ </span></code> is followed by an alphabetic character other than
<code class=scheme>u</code> and then a non-alphabetic character, then the character
constant is terminated. If <code class=scheme><span class=selfeval>#\ </span></code> is followed by a <code class=scheme><span class=selfeval>8</span></code>
or <code class=scheme><span class=selfeval>9</span></code>, then the constant is terminated. If <code class=scheme><span class=selfeval>#\ </span></code> is
followed by a non-alphabetic, non-decimal-digit character then the
constant is terminated.</p>
<p>
<a name="node_idx_2190"></a>
</p>
<li><p>Within string constants, the following escape sequences are
recognized in addition to <tt><tt>\</tt>"</tt> and <tt><tt>\</tt><tt>\</tt></tt>:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2192"></a><tt><tt>\</tt>a</tt>: alarm (ASCII 7)
</p>
<li><p><a name="node_idx_2194"></a><tt><tt>\</tt>b</tt>: backspace (ASCII 8)
</p>
<li><p><a name="node_idx_2196"></a><tt><tt>\</tt>t</tt>: tab (ASCII 9)
</p>
<li><p><a name="node_idx_2198"></a><tt><tt>\</tt>n</tt>: linefeed (ASCII 10)
</p>
<li><p><a name="node_idx_2200"></a><tt><tt>\</tt>v</tt>: vertical tab (ASCII 11)
</p>
<li><p><a name="node_idx_2202"></a><tt><tt>\</tt>f</tt>: formfeed (ASCII 12)
</p>
<li><p><a name="node_idx_2204"></a><tt><tt>\</tt>r</tt>: return (ASCII 13)
</p>
<li><p><a name="node_idx_2206"></a><tt><tt>\</tt>e</tt>: escape (ASCII 27)</p>
<p>
</p>
<li><p><a name="node_idx_2208"></a><tt><tt>\</tt>'</tt>: quote (i.e., the backslash has no effect)</p>
<p>
</p>
<li><p><a name="node_idx_2210"></a><tt><tt>\</tt><code class=scheme><span class=variable>o</span></code></tt>, <a name="node_idx_2212"></a><tt><tt>\</tt><code class=scheme><span class=variable>oo</span></code></tt>, or <a name="node_idx_2214"></a><tt><tt>\</tt><code class=scheme><span class=variable>ooo</span></code></tt>:
Unicode for octal <code class=scheme><span class=variable>o</span></code>, <code class=scheme><span class=variable>oo</span></code>, or <code class=scheme><span class=variable>ooo</span></code>, where each
<code class=scheme><span class=variable>o</span></code> is <code class=scheme>0</code>, <code class=scheme>1</code>, <code class=scheme>2</code>, <code class=scheme>3</code>, <code class=scheme>4</code>,
<code class=scheme>5</code>, <code class=scheme>6</code>, or <code class=scheme>7</code>. The <tt><tt>\</tt><code class=scheme><span class=variable>ooo</span></code></tt> form
takes precedence over the <tt><tt>\</tt><code class=scheme><span class=variable>oo</span></code></tt> form, and
<tt><tt>\</tt><code class=scheme><span class=variable>oo</span></code></tt> takes precedence over <tt><tt>\</tt><code class=scheme><span class=variable>o</span></code></tt>.</p>
<p>
</p>
<li><p><a name="node_idx_2216"></a><tt><tt>\</tt>x<code class=scheme><span class=variable>h</span></code></tt> or <a name="node_idx_2218"></a><tt><tt>\</tt>x<code class=scheme><span class=variable>hh</span></code></tt>: Unicode for hexadecimal
<code class=scheme><span class=variable>h</span></code> or <code class=scheme><span class=variable>hh</span></code>, where each <code class=scheme><span class=variable>h</span></code> is <code class=scheme>0</code>, <code class=scheme>1</code>,
<code class=scheme>2</code>, <code class=scheme>3</code>, <code class=scheme>4</code>, <code class=scheme>5</code>, <code class=scheme>6</code>, <code class=scheme>7</code>, <code class=scheme>a</code>,
<code class=scheme>A</code>, <code class=scheme>b</code>, <code class=scheme>B</code>, <code class=scheme>c</code>, <code class=scheme>C</code>, <code class=scheme>d</code>, <code class=scheme>D</code>,
<code class=scheme>e</code>, <code class=scheme>E</code>, <code class=scheme>f</code>, or <code class=scheme>F</code>. The <tt><tt>\</tt>x<code class=scheme><span class=variable>hh</span></code></tt>
form takes precedence over the <tt><tt>\</tt>x<code class=scheme><span class=variable>h</span></code></tt> form.</p>
<p>
</p>
<li><p><a name="node_idx_2220"></a><tt><tt>\</tt>u<code class=scheme><span class=variable>h</span></code></tt>, <a name="node_idx_2222"></a><tt><tt>\</tt>u<code class=scheme><span class=variable>hh</span></code></tt>,
<a name="node_idx_2224"></a><tt><tt>\</tt>u<code class=scheme><span class=variable>hhh</span></code></tt>, or <a name="node_idx_2226"></a><tt><tt>\</tt>u<code class=scheme><span class=variable>hhhh</span></code></tt>:
like <tt><tt>\</tt>x</tt>, but with up to four hexadecimal digits (longer
sequences take precedence). The resulting hexadecimal number
must be a valid argument to <code class=scheme>integer->char</code>, otherwise
the <a name="node_idx_2228"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2230"></a><tt><tt>\</tt>U<code class=scheme><span class=variable>h</span></code></tt>, <a name="node_idx_2232"></a><tt><tt>\</tt>U<code class=scheme><span class=variable>hh</span></code></tt>, <a name="node_idx_2234"></a><tt><tt>\</tt>U<code class=scheme><span class=variable>hhh</span></code></tt>,
<a name="node_idx_2236"></a><tt><tt>\</tt>U<code class=scheme><span class=variable>hhhh</span></code></tt>, <a name="node_idx_2238"></a><tt><tt>\</tt>U<code class=scheme><span class=variable>hhhhh</span></code></tt>, <a name="node_idx_2240"></a><tt><tt>\</tt>U<code class=scheme><span class=variable>hhhhhh</span></code></tt>,
<a name="node_idx_2242"></a><tt><tt>\</tt>U<code class=scheme><span class=variable>hhhhhhh</span></code></tt>, or <a name="node_idx_2244"></a><tt><tt>\</tt>U<code class=scheme><span class=variable>hhhhhhhh</span></code></tt>:
like <tt><tt>\</tt>x</tt>, but with up to eight hexadecimal digits (longer
sequences take precedence). The resulting hexadecimal number
must be a valid argument to <code class=scheme>integer->char</code>, otherwise
the <a name="node_idx_2246"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
</p>
</ul><p>
Furthermore, a backslash followed by a linefeed, carriage return or
return-linefeed combination is elided, allowing string constants to
span lines. Any other use of backslash within a string constant is an
error.
</p>
<p>
<a name="node_idx_2248"></a>
<a name="node_idx_2250"></a>
</p>
<li><p>A string constant preceded by <code class=scheme><span class=selfeval>#</span></code> is a byte-string
constant. Byte string constants support the same escape sequences as
character strings except <tt><tt>\</tt>u</tt> and <tt><tt>\</tt>U</tt>.</p>
<p>
<a name="node_idx_2252"></a><a name="node_idx_2254"></a>
</p>
<li><p>The sequence <code class=scheme><span class=selfeval>#<<</span></code> starts a <strong>here string</strong><a name="node_idx_2256"></a>. The
characters following <code class=scheme><span class=selfeval>#<<</span></code> until a newline character define a
terminator for the string. The content of the string includes all
characters between the <code class=scheme><span class=selfeval>#<<</span></code> line and a line whose only
content is the specified terminator. More precisely, the content of
the string starts after a newline following <code class=scheme><span class=selfeval>#<<</span></code>, and it ends
before a newline that is followed by the terminator, where the
terminator is itself followed by either a newline or end-of-file. No
escape sequences are recognized between the starting and terminating
lines; all characters are included in the string (and terminator)
literally. A return character is not treated as a line separator in
this context. If no characters appear between <code class=scheme><span class=selfeval>#<<</span></code> and a
newline or end-of-file, or if an end-of-file is encountered before a
terminating line, the <a name="node_idx_2258"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
<a name="node_idx_2260"></a> </p>
<li><p>The syntax for numbers is extended as described in
section <a href="mzscheme-Z-H-3.html#node_sec_3.3">3.3</a>. Numbers containing a decimal point or exponent
(e.g., <code class=scheme><span class=selfeval>1.3</span></code>, <code class=scheme><span class=selfeval>2e78</span></code>) are normally read as inexact. If
the <a name="node_idx_2262"></a><code class=scheme>read-decimal-as-inexact</code> parameter is set to
<code class=scheme><span class=selfeval>#f</span></code>, then such numbers are instead read as exact. The
parameter does not affect the parsing of numbers with an explicit
exactness tag (<code class=scheme><span class=selfeval>#e</span></code> or <code class=scheme><span class=selfeval>#i</span></code>).</p>
<p>
<a name="node_idx_2264"></a> </p>
<li><p>A parenthesized sequence containing two delimited dots
(``<code class=scheme>.</code>'') triggers infix parsing. A single <code class=scheme><span class=variable>datum</span></code> must
appear between the dots, and one or more <code class=scheme><span class=variable>datum</span></code>s must appear
before the first dot and after the last dot:
</p>
<div align=center><table><tr><td>
</td><td><div align=left><pre class=scheme>(<span class=variable>left-datum</span> <tt>···</tt><sup>1</sup> . <span class=variable>first-datum</span> . <span class=variable>right-datum</span> <tt>···</tt><sup>1</sup>)
</pre></div></td><td>
</td></tr></table></div>
The resulting list consists of the <code class=scheme><span class=variable>datum</span></code> between the dots,
followed by the remaining <code class=scheme><span class=variable>datum</span></code>s in order:
<div align=center><table><tr><td>
</td><td><div align=left><pre class=scheme>(<span class=variable>first-datum</span> <span class=variable>left-datum</span> <tt>···</tt><sup>1</sup> <span class=variable>right-datum</span> <tt>···</tt><sup>1</sup>)
</pre></div></td><td>
</td></tr></table></div>
Consequently, the input expression <code class=scheme>(<span class=selfeval>1</span> . <span class=variable><</span> . <span class=selfeval>2</span>)</code> produces
<code class=scheme><span class=selfeval>#t</span></code>, and <code class=scheme>(<span class=selfeval>1</span> <span class=selfeval>2</span> . <span class=variable>+</span> . <span class=selfeval>3</span> <span class=selfeval>4</span> <span class=selfeval>5</span>)</code> produces <code class=scheme><span class=selfeval>15</span></code>.<p>
<a name="node_idx_2266"></a><a name="node_idx_2268"></a><a name="node_idx_2270"></a><a name="node_idx_2272"></a>
</p>
<li><p>When the <a name="node_idx_2274"></a><code class=scheme>read-accept-dot</code> parameter is set to
<code class=scheme><span class=selfeval>#f</span></code>, then a delimited dot (``<code class=scheme>.</code>'') is disallowed in
input. When the <a name="node_idx_2276"></a><code class=scheme>read-accept-quasiquote</code> parameter is set to
<code class=scheme><span class=selfeval>#f</span></code>, then a backquote or comma is disallowed in input. These
modes simplify Scheme's input model for students.</p>
<p>
<a name="node_idx_2278"></a> <a name="node_idx_2280"></a> <a name="node_idx_2282"></a>
</p>
<li><p>MzScheme's identifier and symbol syntax is considerably more
liberal than the syntax specified by <em>R5RS</em>. When input is
scanned for tokens, the following characters delimit an identifier in
addition to whitespace:</p>
<p>
<tt></p>
<p>
" , ' ` ; ( ) [ ] { }
</p>
<p></tt></p>
<p>
In addition, an identifier cannot start with a hash mark
(``<code class=scheme><span class=selfeval>#</span></code>'') unless the hash mark is immediately followed by a
percent sign (``<code class=scheme><span class=variable>%</span></code>''). The only other
special characters are backslash (``<tt>\</tt>'') and quoting
vertical bars (``|''); any other character is used as part of an
identifier.</p>
<p>
Symbols containing special characters (including delimiters) are
expressed using an escaping backslash (``<tt>\</tt>'') or quoting
vertical bars (``|''):
</p>
<ul><p>
</p>
<li><p>A backslash preceding any character includes that character in
the symbol literally; double backslashes produce a single backslash
in the symbol.</p>
<p>
</p>
<li><p>Characters between a pair of vertical bars are included in the
symbol literally. Quoting bars can be used for any part of a symbol,
or the whole symbol can be quoted. Backslashes and quoting bars can
be mixed within a symbol, but a backslash is <em>not</em> a special
character within a pair of quoting bars.</p>
<p>
</p>
</ul><p>
Characters quoted with a backslash or a vertical bar always preserve
their case, even when identifiers are read case-insensitively.</p>
<p>
An input token constructed in this way is an identifier when it is not
a numerical constant (following the extended number syntax described
in section <a href="mzscheme-Z-H-3.html#node_sec_3.3">3.3</a>). A token containing a backslash or vertical bars
is never treated as a numerical constant.</p>
<p>
Examples:
</p>
<ul><p>
</p>
<li><p><code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> a<tt>\</tt>(b)</code> produces the same symbol as
<code class=scheme>(<code class=scheme>string->symbol</code> <span class=selfeval>"a(b"</span>)</code>.</p>
<p>
</p>
<li><p><code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> A<tt>\</tt>B)</code> produces the same
symbol as <code class=scheme>(<code class=scheme>string->symbol</code> <span class=selfeval>"aB"</span>)</code> when identifiers are read
without case-sensitivity.</p>
<p>
</p>
<li><p><code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> a<tt>\</tt> b)</code>, <code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> |a b|)</code>, and
<code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> a| |b)</code> all produce the same symbol as
<code class=scheme>(<code class=scheme>string->symbol</code> <span class=selfeval>"a b"</span>)</code>.</p>
<p>
</p>
<li><p><code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> |a||b|)</code> is the same as <code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> |ab|)</code>,
which produces the same symbol as <code class=scheme>(<code class=scheme>string->symbol</code> <span class=selfeval>"ab"</span>)</code>.</p>
<p>
</p>
<li><p><code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> 10)</code> is the number 10, but <code class=scheme>(<code class=scheme><span class=keyword>quote</span></code> |10|)</code>
produces the same symbol as <code class=scheme>(<code class=scheme>string->symbol</code> <span class=selfeval>"10"</span>)</code>.</p>
<p>
</p>
</ul><p></p>
<p>
Whether a vertical bar is used as a special or normal symbol character
is controlled with the <a name="node_idx_2284"></a><code class=scheme>read-accept-bar-quote</code> boolean
parameter (see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.3">7.9.1.3</a>). Vertical bar quotes
are enabled by default. Quoting backslashes cannot be disabled.</p>
<p>
<a name="node_idx_2286"></a>
</p>
<li><p>By default, symbols are read case-sensitively. Case
sensitivity for reading can be controlled in three ways:</p>
<p>
</p>
<ul><p>
</p>
<li><p>Quoting part of a symbol with an escaping backslash
(``<tt>\</tt>'') or quoting vertical bar (``|'') always
preserves the case of the quoted portion, as described above.</p>
<p>
</p>
<li><p><a name="node_idx_2288"></a> <a name="node_idx_2290"></a> The sequence <code class=scheme>#cs</code> can
be used as a prefix for any expression to make reading symbols
within the expression case-sensitive. A <code class=scheme>#ci</code> prefix
similarly makes reading symbols in an expression case-insensitive.
Whitespace can appear between a <code class=scheme>#cs</code> or <code class=scheme>#ci</code>
prefix and its expression, and prefixes can be nested. Backslash and
vertical-bar quotes override a <code class=scheme>#ci</code> prefix.</p>
<p>
</p>
<li><p>When the <a name="node_idx_2292"></a><code class=scheme>read-case-sensitive</code> parameter (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.3">7.9.1.3</a>) is set to <code class=scheme><span class=selfeval>#t</span></code>, then case is
preserved when reading symbols. The default is <code class=scheme><span class=selfeval>#t</span></code>, and it
is set to <code class=scheme><span class=selfeval>#t</span></code> while loading a module (see
section <a href="mzscheme-Z-H-5.html#node_sec_5.8">5.8</a>). A <code class=scheme>#cs</code> or <code class=scheme>#ci</code> prefix
overrides the parameter setting, as does backslash or vertical-bar
quoting.</p>
<p>
</p>
</ul><p>
Symbol case conversions are <em>not</em> sensitive to the current locale
(see section <a href="mzscheme-Z-H-1.html#node_sec_1.2.2">1.2.2</a>).</p>
<p>
<a name="node_idx_2294"></a> <a name="node_idx_2296"></a> <a name="node_idx_2298"></a> <a name="node_idx_2300"></a>
</p>
<li><p>A symbol-like expression that starts with an unquoted hash and
colon (``#:'') is parsed as a keyword constant. After the leading
colon, backslashes, vertical bars, and case sensitivity are handled
as for symbols, except that a keyword expression can never be
interpreted as a number.</p>
<p>
<a name="node_idx_2302"></a>
<a name="node_idx_2304"></a>
<a name="node_idx_2306"></a>
</p>
<li><p>Expressions of the form <code class=scheme>#rx<code class=scheme><span class=variable>string</span></code></code> are literal
regexp values (see section <a href="mzscheme-Z-H-10.html#node_chap_10">10</a>) where <code class=scheme><span class=variable>string</span></code> is a string
constant. The regexp produced by <code class=scheme>#rx<code class=scheme><span class=variable>string</span></code></code> is the
same as produced by <code class=scheme>(regexp <code class=scheme><span class=variable>string</span></code>)</code>. If <code class=scheme><span class=variable>string</span></code>
is not a valid pattern, the <a name="node_idx_2308"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
Expressions of the form <code class=scheme>#rx#<code class=scheme><span class=variable>string</span></code></code> are similarly literal
byte-regexp values. The regexp produced by <code class=scheme>#rx#<code class=scheme><span class=variable>string</span></code></code> is the
same as produced by <code class=scheme>(byte-regexp #<code class=scheme><span class=variable>string</span></code>)</code>.</p>
<p>
<a name="node_idx_2310"></a>
<a name="node_idx_2312"></a>
<a name="node_idx_2314"></a>
</p>
<li><p>Expressions of the form <code class=scheme>#hash((<code class=scheme><span class=variable>key-datum</span></code>
. <code class=scheme><span class=variable>val-datum</span></code>) <tt>···</tt>)</code> are literal immutable hash tables. The
hash table maps each <code class=scheme><span class=variable>key-datum</span></code> to its <code class=scheme><span class=variable>val-datum</span></code>,
comparing keys with <code class=scheme><code class=scheme>equal?</code></code>. The table is constructed by
adding each <code class=scheme><span class=variable>key-datum</span></code> mapping from left to right, so later
mappings can hide earlier mappings if the <code class=scheme><span class=variable>key-datum</span></code>s are
<code class=scheme><code class=scheme>equal?</code></code>. An expression of the form
<code class=scheme>#hasheq((<code class=scheme><span class=variable>key-datum</span></code> . <code class=scheme><span class=variable>val-datum</span></code>) <tt>···</tt>)</code>
produces an immutable hash table with keys compared using
<code class=scheme><code class=scheme>eq?</code></code>. If the value of <a name="node_idx_2316"></a><code class=scheme>read-square-bracket-as-paren</code>
parameter (see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.3">7.9.1.3</a>) is true,
matching parentheses in a <code class=scheme>#hash</code> or <code class=scheme>#hasheq</code>
constant can be replaced by matching square brackets. Similarly,
matching curly braces can be used if
<a name="node_idx_2318"></a><code class=scheme>read-curly-brace-as-paren</code> is true.</p>
<p>
<a name="node_idx_2320"></a> <a name="node_idx_2322"></a> <a name="node_idx_2324"></a>
</p>
<li><p>Values with shared structure are expressed using
<code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> and <code class=scheme>#<code class=scheme><span class=variable>n</span></code>#</code>, where <code class=scheme><span class=variable>n</span></code> is
a decimal integer. See section <a href="#node_sec_11.2.5.1">11.2.5.1</a>.</p>
<p>
<a name="node_idx_2326"></a>
</p>
<li><p>Expressions of the form <code class=scheme>#%<code class=scheme><span class=variable>x</span></code></code> are symbols, where
<code class=scheme><span class=variable>x</span></code> can be a symbol or a number.</p>
<p>
<a name="node_idx_2328"></a>
</p>
<li><p>Expressions beginning with <code class=scheme><span class=selfeval>#~</span></code> are interpreted as
compiled MzScheme code. See section <a href="mzscheme-Z-H-14.html#node_sec_14.3">14.3</a>.</p>
<p>
<a name="node_idx_2330"></a>
</p>
<li><p>Multi-line comments are started with <code class=scheme>#<tt>|</tt></code> and terminated
with <code class=scheme><tt>|</tt>#</code>. Comments of this form can be nested arbitrarily.</p>
<p>
<a name="node_idx_2332"></a>
<a name="node_idx_2334"></a>
</p>
<li><p>A <code class=scheme>#;</code> comments out the next datum. Whitespace and
comments (including <code class=scheme>#;</code> comments) may appear between the
<code class=scheme>#;</code> and the commented-out datum. Graph-structure annotations
with <code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> and <code class=scheme>#<code class=scheme><span class=variable>n</span></code>#</code> work within the
comment as if the datum were not commented out (e.g., bindings can be
introduced with <code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> for use in parts of the datum
that are not commented out). When <code class=scheme>#;</code> appears at the
beginning of a top-level datum, however, graph-structure bindings are
discarded (along with the first following datum) before reading the
second following datum.</p>
<p>
<a name="node_idx_2336"></a>
<a name="node_idx_2338"></a>
</p>
<li><p>If the first line of a <code class=scheme><code class=scheme>load</code></code>ed file begins with
<code class=scheme><span class=selfeval>#!</span></code>, it is ignored by the default load handler. If an ignored
line ends with a backslash (``<tt>\</tt>''), then the next line is
also ignored. (The <code class=scheme><span class=selfeval>#!</span></code> convention is for shell scripts; see
Chapter <a href="mzscheme-Z-H-18.html#node_chap_18">18</a> for details.)</p>
<p>
<a name="node_idx_2340"></a> <a name="node_idx_2342"></a>
</p>
<li><p>A <code class=scheme>#hx</code> shifts the reader into H-expression mode (see
section <a href="mzscheme-Z-H-19.html#node_chap_19">19</a>) for one H-expression. A <code class=scheme>#sx</code> has no effect in
normal mode, but in H-expression mode, it shifts the reader back to
(normal) S-expression mode. The <code class=scheme>read-honu</code> and
<code class=scheme>read-honu-syntax</code> procedures read as if the stream starts
with <code class=scheme>#hx</code>.</p>
<p>
<a name="node_idx_2344"></a>
</p>
<li><p>A <code class=scheme>#honu</code> shifts the reader into H-expression mode (see
section <a href="mzscheme-Z-H-19.html#node_chap_19">19</a>) and reads repeatedly until an end-of-file is
encountered. The H-expression results are wrapped in a module-formed
S-expression, as described in section <a href="mzscheme-Z-H-19.html#node_chap_19">19</a>.</p>
<p>
<a name="node_idx_2346"></a>
</p>
<li><p>A <code class=scheme>#reader</code> must be followed by a datum. The datum is
passed to the procedure that is the value of the
<code class=scheme>current-reader-guard</code> parameter (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.3">7.9.1.3</a>), and the result is used as a module
path. The module path is passed to <code class=scheme>dynamic-require</code> (see
section <a href="mzscheme-Z-H-5.html#node_sec_5.5">5.5</a>) with either <code class=scheme><span class=selfeval>'read</span></code> or <code class=scheme><span class=selfeval>'read-syntax</span></code>
(depending on whether parsing started with <code class=scheme>read</code> or
<code class=scheme>read-syntax</code>). The resulting procedure should accept the same
arguments as <code class=scheme>read</code> or <code class=scheme>read-syntax</code> (with all optional
arguments as required). The procedure is given the port whose stream
contained <code class=scheme>#reader</code>, and it should produce a datum result. If
the result is a syntax object in <code class=scheme>read</code> mode it is converted
to a datum using <code class=scheme>syntax-object->datum</code>; if the result is not
a syntax object in <code class=scheme>read-syntax</code> mode, it is converted to one
using <code class=scheme>datum->syntax-object</code>. See also
section <a href="#node_sec_11.2.9.1">11.2.9.1</a> and section <a href="#node_sec_11.2.9.2">11.2.9.2</a> for
information on special-comment results and recursive reads. If the
<code class=scheme>read-accept-reader</code> parameter is set to <code class=scheme><span class=selfeval>#f</span></code>, then
<code class=scheme>#reader</code> is disallowed as input.</p>
<p>
</p>
</ul><p></p>
<p>
Reading from a custom port can produce arbitrary values generated by
the port; see section <a href="#node_sec_11.1.7">11.1.7</a> for details. If the port generates
a non-character value in a position where a character is required
(e.g., within a string), the <a name="node_idx_2348"></a><code class=scheme>exn:fail:read:non-char</code> exception is raised.</p>
<p>
</p>
<a name="node_sec_11.2.5"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.5">11.2.5 Default Printer</a></h3>
<p></p>
<p>
<a name="node_idx_2350"></a>
<a name="node_idx_2352"></a>
MzScheme's printer obeys the following non-standard rules (though the
rules for <code class=scheme><code class=scheme>print</code></code> do not apply when the <code class=scheme>print-honu</code>
parameter is set to <code class=scheme><span class=selfeval>#t</span></code>; see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.4">7.9.1.4</a>).
</p>
<ul><p>
<a name="node_idx_2354"></a>
</p>
<li><p>A vector can be printed by <code class=scheme><code class=scheme>write</code></code> and <code class=scheme><code class=scheme>print</code></code> using
the shorthand described in section <a href="#node_sec_11.2.4">11.2.4</a>, where the vector's
length is printed between the leading <code class=scheme><span class=selfeval>#</span></code> and the opening
parenthesis and repeated tail elements are omitted. For example,
<code class=scheme><span class=selfeval>#</span>(<span class=selfeval>1</span> <span class=selfeval>2</span> <span class=selfeval>2</span> <span class=selfeval>2</span>)</code> is printed as <code class=scheme><span class=selfeval>#4</span>(<span class=selfeval>1</span> <span class=selfeval>2</span>)</code>. The <code class=scheme><code class=scheme>display</code></code>
procedure does not output vectors using this shorthand. Shorthand
vector printing is controlled with the <a name="node_idx_2356"></a><code class=scheme>print-vector-length</code>
boolean parameter (see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.4">7.9.1.4</a>). Shorthand
vector printing is enabled by default.</p>
<p>
<a name="node_idx_2358"></a>
</p>
<li><p>Boxes (see section <a href="mzscheme-Z-H-3.html#node_sec_3.11">3.11</a>) can be printed with the <code class=scheme><span class=selfeval>#&</span></code>
notation (see section <a href="#node_sec_11.2.4">11.2.4</a>). When box printing is disabled, all
boxes are printed un<code class=scheme><code class=scheme>read</code></code>ably as <code class=scheme><span class=selfeval>#<box></span></code>. Box
printing is controlled with the <a name="node_idx_2360"></a><code class=scheme>print-box</code> boolean
parameter (see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.4">7.9.1.4</a>). Box printing is enabled by
default.</p>
<p>
<a name="node_idx_2362"></a>
</p>
<li><p>Structures (see Chapter <a href="mzscheme-Z-H-4.html#node_chap_4">4</a>) can be printed using
either a custom-write procedure or vector notation. See
section <a href="#node_sec_11.2.10">11.2.10</a> for information on custom-write procedures; the
following information applies only when no custom-write procedure is
specified. In the vector form of output, the first item is a symbol
of the form <code class=scheme>struct:<code class=scheme><span class=variable>s</span></code></code> -- where <code class=scheme><span class=variable>s</span></code> is the name of
the structure -- and the remaining elements are the elements of the
structure, but the vector exposes only as much information about the
structure as the current inspector can access (see
section <a href="mzscheme-Z-H-4.html#node_sec_4.5">4.5</a>). When structure printing is disabled, or when no
part of the structure is accessible to the current inspector, a
structure is printed un<code class=scheme><code class=scheme>read</code></code>ably as
<code class=scheme>#<struct:<code class=scheme><span class=variable>s</span></code>></code>. Structure printing is controlled with
the <a name="node_idx_2364"></a><code class=scheme>print-struct</code> boolean parameter (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.4">7.9.1.4</a>). Structure printing is disabled by default.</p>
<p>
<a name="node_idx_2366"></a>
</p>
<li><p>Symbols containing spaces or special characters <code class=scheme><code class=scheme>write</code></code>
using escaping backslashes and quoting vertical bars. When
the <a name="node_idx_2368"></a><code class=scheme>read-case-sensitive</code> parameter is set to <code class=scheme><span class=selfeval>#f</span></code>,
then symbols containing uppercase characters also use escaping
backslashes or quoting vertical bars. In addition, symbols are quoted
with vertical bars or a leading backslash when they would otherwise
print the same as a numerical constant. If the value of
the <a name="node_idx_2370"></a><code class=scheme>read-accept-bar-quote</code> boolean parameter is <code class=scheme><span class=selfeval>#f</span></code>
(see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.3">7.9.1.3</a>), then backslashes are always
used to escape special characters instead of quoting them with
vertical bars, and a vertical bar is not treated as a special
character. Otherwise, quoting bars are used in printing when bar at
the beginning and one at the end suffices to correctly print the
symbol. See section <a href="#node_sec_11.2.4">11.2.4</a> for more information about symbol
parsing. Symbols <code class=scheme><code class=scheme>display</code></code> without escaping or quoting special
characters.</p>
<p>
<a name="node_idx_2372"></a>
</p>
<li><p>Keywords <code class=scheme>write</code> and <code class=scheme>display</code> the same as
symbols, except with a leading hash and colon, and without special handing when
the printed form matches a number (since the leading <code class=scheme>#:</code>
distinguishes the keyword).</p>
<p>
<a name="node_idx_2374"></a>
</p>
<li><p>Characters with the special names described in section <a href="#node_sec_11.2.4">11.2.4</a>
<code class=scheme><code class=scheme>write</code></code> using the same name. (Some characters have multiple
names; the <code class=scheme><span class=selfeval>#\newline</span></code> and <code class=scheme><span class=selfeval>#\nul</span></code> names are used
instead of <code class=scheme><span class=selfeval>#\linefeed</span></code> and <code class=scheme><span class=selfeval>#\null</span></code>). Other graphic
characters (according to <code class=scheme>char-graphic?</code>; see
section <a href="mzscheme-Z-H-3.html#node_sec_3.4">3.4</a>) <code class=scheme><code class=scheme>write</code></code> as <code class=scheme><span class=selfeval>#\ </span></code> followed by the
single character, and all others characters are written in
<code class=scheme><span class=selfeval>#\u</span></code> notation with four digits or <code class=scheme><span class=selfeval>#\U</span></code> notation with
eight digits (using the latter only if the character value it does
not fit in four digits). All characters <code class=scheme><code class=scheme>display</code></code> as a single
character.</p>
<p>
<a name="node_idx_2376"></a>
</p>
<li><p>Strings containing non-graphic, non-blank characters (according
to <code class=scheme>char-graphic?</code> and <code class=scheme>char-blank?</code>; see
section <a href="mzscheme-Z-H-3.html#node_sec_3.4">3.4</a>) <code class=scheme><code class=scheme>write</code></code> using the escape sequences
described in section <a href="#node_sec_11.2.4">11.2.4</a>, using <tt><tt>\</tt>a</tt>, <tt><tt>\</tt>b</tt>,
<tt><tt>\</tt>t</tt>, <tt><tt>\</tt>n</tt>, <tt><tt>\</tt>v</tt>, <tt><tt>\</tt>f</tt>, <tt><tt>\</tt>r</tt>, or
<tt><tt>\</tt>e</tt> if possible, otherwise using <tt><tt>\</tt>u</tt> with four
hexadecimal digits or <tt><tt>\</tt>U</tt> with eight hexadecimal digits (using
the latter only if the character value does not fit into four
digits). All strings <code class=scheme><code class=scheme>display</code></code> as their literal character
sequences.</p>
<p>
<a name="node_idx_2378"></a>
</p>
<li><p>Byte strings <code class=scheme><code class=scheme>write</code></code> using <code class=scheme>#"</code>, where each byte
in the string content is written using the corresponding ASCII
decoding if the byte is between 0 and 127 and the character is
graphic or blank (according to <code class=scheme>char-graphic?</code> and
<code class=scheme>char-blank?</code>; see section <a href="mzscheme-Z-H-3.html#node_sec_3.4">3.4</a>). Otherwise, the byte
is written using <tt><tt>\</tt>a</tt>, <tt><tt>\</tt>b</tt>, <tt><tt>\</tt>t</tt>, <tt><tt>\</tt>n</tt>,
<tt><tt>\</tt>v</tt>, <tt><tt>\</tt>f</tt>, <tt><tt>\</tt>r</tt>, or <tt><tt>\</tt>e</tt> if possible,
otherwise using <tt><tt>\</tt>o</tt> with one to three octal digits (only as
many as necessary). All strings <code class=scheme><code class=scheme>display</code></code> as their literal
byte sequence; this byte sequence may not be a valid UTF-8 encoding,
so it may not correspond to a sequence of characters.</p>
<p>
<a name="node_idx_2380"></a>
</p>
<li><p>Regexp values print using the form <code class=scheme>#rx<code class=scheme><span class=variable>string</span></code></code>,
where <code class=scheme><span class=variable>string</span></code> is the <code class=scheme><code class=scheme>write</code></code> form of the regexp's source
character string or byte string. Similarly, byte-regexp values
print starting with <code class=scheme>#rx#</code>.</p>
<p>
<a name="node_idx_2382"></a>
</p>
<li><p>Paths <code class=scheme><code class=scheme>write</code></code> like other un<code class=scheme><code class=scheme>read</code></code>able values
using <code class=scheme><span class=variable>#<path:...></span></code>, but a path <code class=scheme><code class=scheme>display</code></code>s like the
result of <code class=scheme>path->string</code> applied to the path.</p>
<p>
<a name="node_idx_2384"></a>
</p>
<li><p>When the <code class=scheme>print-hash-table</code> parameter is set to true
(see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.4">7.9.1.4</a>), hash tables print using the form
<code class=scheme>#hash((<code class=scheme><span class=variable>key</span></code> . <code class=scheme><span class=variable>val</span></code>) <tt>···</tt>)</code> or
<code class=scheme>#hasheq((<code class=scheme><span class=variable>key</span></code> . <code class=scheme><span class=variable>val</span></code>) <tt>···</tt>)</code> for tables using
<code class=scheme><code class=scheme>equal?</code></code> or <code class=scheme><code class=scheme>eq?</code></code> key comparisons, respectively. If
the <code class=scheme>print-hash-table</code> parameter's value is <code class=scheme><span class=selfeval>#f</span></code>, hash
tables print un<code class=scheme><code class=scheme>read</code></code>ably as <code class=scheme><span class=selfeval>#<hash-table></span></code>. Hash
tables with weakly held keys always print un<code class=scheme><code class=scheme>read</code></code>ably as
<code class=scheme><span class=selfeval>#<hash-table></span></code>.</p>
<p>
<a name="node_idx_2386"></a>
</p>
<li><p>Values with shared structure can be printed using
<code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> and <code class=scheme>#<code class=scheme><span class=variable>n</span></code>#</code>, where <code class=scheme><span class=variable>n</span></code> is a
decimal integer. See section <a href="#node_sec_11.2.5.1">11.2.5.1</a>.</p>
<p>
<a name="node_idx_2388"></a>
</p>
<li><p>A value with no <code class=scheme><code class=scheme>read</code></code>able format prints as
<code class=scheme><span class=selfeval>#<...></span></code>, but only when the <code class=scheme>print-unreadable</code>
parameter is set to <code class=scheme><span class=selfeval>#t</span></code> (the default; see also
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.4">7.9.1.4</a>). When the parameter's value is
<code class=scheme><span class=selfeval>#f</span></code>, attempting to print an un<code class=scheme><code class=scheme>read</code></code>able value raises
<a name="node_idx_2390"></a><code class=scheme>exn:fail:contract</code>.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.2.5.1"></a>
<h4><a href="mzscheme.html#node_toc_node_sec_11.2.5.1">11.2.5.1 Sharing Structure in Input and Output</a></h4>
<p></p>
<p>
<a name="node_idx_2392"></a> <a name="node_idx_2394"></a>
<a name="node_idx_2396"></a>
<a name="node_idx_2398"></a>
MzScheme can read and print Common LISP-style <strong>graphs</strong>, values
with shared structure (including cycles). Graphs are described by
tagging the shared structure once with <code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> (using
some decimal integer <code class=scheme><span class=variable>n</span></code> with no more than eight digits) and then
referencing it later with <code class=scheme>#<code class=scheme><span class=variable>n</span></code>#</code> (using the same number
<code class=scheme><span class=variable>n</span></code>). For example, the following datum represents the infinite
list of ones:
</p>
<div align=left><pre class=scheme><span class=selfeval>#0=</span>(<span class=selfeval>1</span> . <span class=selfeval>#0#</span>)
</pre></div><p>
If this graph is entered into MzScheme's <code class=scheme>read</code>-<code class=scheme>eval</code>-<code class=scheme>print</code> loop, MzScheme's compiler
will loop forever, trying to compile an infinite expression. In
contrast, the following expression defines <code class=scheme><span class=variable>ones</span></code> to the
infinite list of ones, using <code class=scheme><span class=keyword>quote</span></code> to hide the infinite list
from the compiler:
</p>
<div align=left><pre class=scheme>(<span class=keyword>define</span> <span class=variable>ones</span> (<span class=keyword>quote</span> <span class=selfeval>#0=</span>(<span class=selfeval>1</span> . <span class=selfeval>#0#</span>)))
</pre></div><p>
A tagged structure can be referenced multiple
times. Here, <code class=scheme><span class=variable>v</span></code> is defined to be a vector containing the same
<code class=scheme><code class=scheme>cons</code></code> cell in all three slots:
</p>
<div align=left><pre class=scheme>(<span class=keyword>define</span> <span class=variable>v</span> <span class=selfeval>#</span>(<span class=selfeval>#1=</span>(<code class=scheme>cons</code> <span class=selfeval>1</span> <span class=selfeval>2</span>) <span class=selfeval>#1#</span> <span class=selfeval>#1#</span>))
</pre></div><p>
A tag <code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> must appear to the left of all references
<code class=scheme>#<code class=scheme><span class=variable>n</span></code>#</code>, and all references must appear in the same
top-level datum as the tag. By default, MzScheme's printer will
display a value without showing the shared structure:
</p>
<div align=left><pre class=schemeresponse><span class=selfeval>#</span>((<span class=selfeval>1</span> . <span class=selfeval>2</span>) (<span class=selfeval>1</span> . <span class=selfeval>2</span>) (<span class=selfeval>1</span> . <span class=selfeval>2</span>))
</pre></div><p></p>
<p>
Graph reading and printing are controlled with the
<a name="node_idx_2400"></a><code class=scheme>read-accept-graph</code> and <a name="node_idx_2402"></a><code class=scheme>print-graph</code> boolean
parameters (see section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.4">7.9.1.4</a>). Graph reading is enabled by
default, and graph printing is disabled by default. However, when the
printer encounters a graph containing a <a name="node_idx_2404"></a> cycle, graph
printing is automatically enabled, temporarily. (For this reason, the
<a name="node_idx_2406"></a><code class=scheme>display</code>, <a name="node_idx_2408"></a><code class=scheme>write</code>, and <a name="node_idx_2410"></a><code class=scheme>print</code> procedures
require memory proportional to the depth of the value being printed.)
When graph reading is disabled and a graph is provided as input, the
<a name="node_idx_2412"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
If the <code class=scheme><span class=variable>n</span></code> in a <code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> form or a <code class=scheme>#<code class=scheme><span class=variable>n</span></code>#</code> form
contains more than eight digits, the <a name="node_idx_2414"></a><code class=scheme>exn:fail:read</code> exception is raised. If a
<code class=scheme>#<code class=scheme><span class=variable>n</span></code>#</code> form is not preceded by a <code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> form
using the same <code class=scheme><span class=variable>n</span></code>, the <a name="node_idx_2416"></a><code class=scheme>exn:fail:read</code> exception is raised. If two
<code class=scheme>#<code class=scheme><span class=variable>n</span></code>=</code> forms are in the same expression for the same
<code class=scheme><span class=variable>n</span></code>, the <a name="node_idx_2418"></a><code class=scheme>exn:fail:read</code> exception is raised.</p>
<p>
</p>
<a name="node_sec_11.2.6"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.6">11.2.6 Replacing the Reader</a></h3>
<p></p>
<p>
Each input port has its own <strong>port read handler</strong><a name="node_idx_2420"></a>. This handler
is invoked to read from the port when the built-in <code class=scheme><code class=scheme>read</code></code> or
<code class=scheme><code class=scheme>read-syntax</code></code> procedure is applied to the port.<a name="node_call_footnote_34"></a><a href="#node_footnote_34"><sup><small>34</small></sup></a> A port read handler is applied to
either one argument or two arguments:
</p>
<ul><p>
</p>
<li><p>A single argument is supplied when the port is used
with <code class=scheme><code class=scheme>read</code></code>; the argument is the port being read. The return
value is the value that was read from the port. </p>
<p>
</p>
<li><p>Two arguments are supplied when the port is used with
<code class=scheme><code class=scheme>read-syntax</code></code>; the first argument is the port being read, and
the second argument is a value indicating the source. The return
value is a syntax object that was read from the port.</p>
<p>
</p>
</ul><p></p>
<p>
A port's read handler is configured with <code class=scheme><code class=scheme>port-read-handler</code></code>:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2422"></a><a name="node_kw_definitionport-read-handler"></a><code class=scheme>(port-read-handler</code><tt> </tt><code class=scheme><span class=variable>input-port</span></code><code class=scheme>)</code>
returns the current port read handler for <code class=scheme><span class=variable>input-port</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2424"></a><a name="node_kw_definitionport-read-handler/set"></a><code class=scheme>(port-read-handler</code><tt> </tt><code class=scheme><span class=variable>input-port proc</span></code><code class=scheme>)</code>
sets the handler for <code class=scheme><span class=variable>input-port</span></code> to <code class=scheme><span class=variable>proc</span></code>.</p>
<p>
</p>
</ul><p></p>
<p>
The default port read handler reads standard Scheme expressions with
MzScheme's built-in parser (see section <a href="#node_sec_11.2.4">11.2.4</a>). It handles a
special result from a custom input port (see section <a href="#node_sec_11.1.7.1">11.1.7.1</a>) by
treating it as a single expression, except that special-comment
values (see section <a href="#node_sec_11.2.9.1">11.2.9.1</a>) are treated as whitespace.</p>
<p>
The <code class=scheme>read</code> and <code class=scheme>read-syntax</code> procedures themselves can
be customized through a readtable; see section <a href="#node_sec_11.2.8">11.2.8</a> for more
information.</p>
<p>
</p>
<a name="node_sec_11.2.7"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.7">11.2.7 Replacing the Printer</a></h3>
<p></p>
<p>
Each output port has its own <strong>port display handler</strong><a name="node_idx_2426"></a>,
<strong>port write handler</strong><a name="node_idx_2428"></a>, and <strong>port print
handler</strong><a name="node_idx_2430"></a>. These handlers are invoked to output to the port when the
standard <code class=scheme><code class=scheme>display</code></code>, <code class=scheme><code class=scheme>write</code></code> or <code class=scheme><code class=scheme>print</code></code> procedure
is applied to the port. A port display/write/print handler takes a
two arguments: the value to be printed and the destination port. The
handler's return value is ignored.</p>
<p>
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2432"></a><a name="node_kw_definitionport-display-handler"></a><code class=scheme>(port-display-handler</code><tt> </tt><code class=scheme><span class=variable>output-port</span></code><code class=scheme>)</code> returns the
current port display handler for <code class=scheme><span class=variable>output-port</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2434"></a><a name="node_kw_definitionport-display-handler/set"></a><code class=scheme>(port-display-handler</code><tt> </tt><code class=scheme><span class=variable>output-port proc</span></code><code class=scheme>)</code> sets the
display handler for <code class=scheme><span class=variable>output-port</span></code> to <code class=scheme><span class=variable>proc</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2436"></a><a name="node_kw_definitionport-write-handler"></a><code class=scheme>(port-write-handler</code><tt> </tt><code class=scheme><span class=variable>output-port</span></code><code class=scheme>)</code> returns the current
port write handler for <code class=scheme><span class=variable>output-port</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2438"></a><a name="node_kw_definitionport-write-handler/set"></a><code class=scheme>(port-write-handler</code><tt> </tt><code class=scheme><span class=variable>output-port proc</span></code><code class=scheme>)</code> sets the write
handler for <code class=scheme><span class=variable>output-port</span></code> to <code class=scheme><span class=variable>proc</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2440"></a><a name="node_kw_definitionport-print-handler"></a><code class=scheme>(port-print-handler</code><tt> </tt><code class=scheme><span class=variable>output-port</span></code><code class=scheme>)</code> returns the current
port print handler for <code class=scheme><span class=variable>output-port</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2442"></a><a name="node_kw_definitionport-print-handler/set"></a><code class=scheme>(port-print-handler</code><tt> </tt><code class=scheme><span class=variable>output-port proc</span></code><code class=scheme>)</code>
sets the print handler for <code class=scheme><span class=variable>output-port</span></code> to <code class=scheme><span class=variable>proc</span></code>.</p>
<p>
</p>
</ul><p></p>
<p>
The default port display and write handlers print Scheme expressions
with MzScheme's built-in printer (see section <a href="#node_sec_11.2.5">11.2.5</a>). The default
print handler calls the global port print handler (the value of the
<a name="node_idx_2444"></a><code class=scheme>global-port-print-handler</code> parameter; see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.2">7.9.1.2</a>); the default global port print
handler is the same as the default write handler.</p>
<p>
</p>
<a name="node_sec_11.2.8"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.8">11.2.8 Customizing the Reader through Readtables</a></h3>
<p></p>
<p>
A <strong>readtable</strong><a name="node_idx_2446"></a> configures MzScheme's built-in reader by
adjusting the way that individual characters are parsed. MzScheme
readtables are just like readtables in Common LISP, except that an
individual readtable is immutable, and the procedures for creating and
inspecting readtables are somewhat different than the Common LISP
procedures.</p>
<p>
In many contexts, <code class=scheme><span class=selfeval>#f</span></code> identifies the default readtable for
MzScheme. In particular, <code class=scheme><span class=selfeval>#f</span></code> is the initial value for the
<code class=scheme>current-readtable</code> parameter (see
section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.3">7.9.1.3</a>), which causes the reader to behave as
described in section <a href="#node_sec_11.2.4">11.2.4</a>. Adjust MzScheme's default reader by
setting the <code class=scheme>current-readtable</code> parameter to a readtable
created with <code class=scheme>make-readtable</code>.</p>
<p>
<a name="node_idx_2448"></a><a name="node_kw_definitionmake-readtable"></a><code class=scheme>(make-readtable</code><tt> </tt><code class=scheme><span class=variable>readtable</span></code><tt> </tt>[<code class=scheme><span class=variable>char-or-false symbol-or-char
readtable-or-proc</span></code><tt> </tt><tt>···</tt><sup>1</sup>]<code class=scheme>)</code> creates a new readtable that is like
<code class=scheme><span class=variable>readtable</span></code> (which can be <code class=scheme><span class=selfeval>#f</span></code>), except that the reader's
behavior is modified for each <code class=scheme><span class=variable>char</span></code> according to the given
<code class=scheme><span class=variable>symbol-or-char</span></code> and <code class=scheme><span class=variable>readtable-or-proc</span></code>. The <tt>···</tt><sup>1</sup> for
<code class=scheme>make-readtable</code> applies to all three of <code class=scheme><span class=variable>char</span></code>,
<code class=scheme><span class=variable>symbol-or-char</span></code>, and <code class=scheme><span class=variable>readtable-or-proc</span></code>; in other words,
the total number of arguments to <code class=scheme>make-readtable</code> must be one
modulo three.</p>
<p>
The possible combinations for <code class=scheme><span class=variable>char-or-false</span></code>, <code class=scheme><span class=variable>symbol-or-char</span></code>, and
<code class=scheme><span class=variable>readtable-or-proc</span></code> are as follows:
</p>
<ul><p>
</p>
<li><p><code class=scheme><span class=variable>char</span></code><tt> </tt><code class=scheme><span class=selfeval>'terminating-macro</span></code><tt> </tt><code class=scheme><span class=variable>proc</span></code> -- causes
<code class=scheme><span class=variable>char</span></code> to be parsed as a delimiter, and an unquoted/uncommented
<code class=scheme><span class=variable>char</span></code> in the input string triggers a call to the
<strong>reader macro</strong><a name="node_idx_2450"></a> <code class=scheme><span class=variable>proc</span></code>; the activity of <code class=scheme><span class=variable>proc</span></code> is
described further below. Conceptually, characters like semi-colon
(``;'') and parentheses are mapped to terminating reader macros in
the default readtable.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>char</span></code><tt> </tt><code class=scheme><span class=selfeval>'non-terminating-macro</span></code><tt> </tt><code class=scheme><span class=variable>proc</span></code> -- like
the <code class=scheme><span class=selfeval>'terminating-macro</span></code> variant, but <code class=scheme><span class=variable>char</span></code> is not treated
as a delimiter, so it can be used in the middle of an
identifier. Conceptually, hash (``#'') is mapped to a
non-terminating macro in the default readtable.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>char</span></code><tt> </tt><code class=scheme><span class=selfeval>'dispatch-macro</span></code><tt> </tt><code class=scheme><span class=variable>proc</span></code> -- like the
<code class=scheme><span class=selfeval>'non-terminating-macro</span></code> variant, but <code class=scheme><span class=variable>char</span></code> only when it
follows a hash (``#'') -- or, more precisely, when the character
follows one that has been mapped to the behavior of hash in the
default readtable.</p>
<p>
</p>
<li><p><code class=scheme><span class=variable>char</span></code><tt> </tt><code class=scheme><span class=variable>like-char</span></code><tt> </tt><code class=scheme><span class=variable>readtable</span></code> -- causes
<code class=scheme><span class=variable>char</span></code> to be parsed in the same way that <code class=scheme><span class=variable>like-char</span></code> is
parsed in <code class=scheme><span class=variable>readtable</span></code>, where <code class=scheme><span class=variable>readtable</span></code> can be <code class=scheme><span class=selfeval>#f</span></code>
to indicate the default readtable. Mapping a character to the same
actions as vertical bar (``|'') in the default reader means that
the character starts quoting for symbols, and the same character
terminates the quote; in contrast, mapping a character to the same
action as a parenthesis or double quote means that the character
starts a list or string, but the list or string is still terminated
with a closing parenthesis or double quote. Finally, mapping a
character to an action in the default readtable means that the
character's behavior is sensitive to parameters that affect the
original character; for example, mapping a character to the same
action is a curly brace (``{'') in the default readtable means that
the character is disallowed when the
<code class=scheme>read-curly-brace-as-paren</code> parameter is set to <code class=scheme><span class=selfeval>#f</span></code>.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>#f</span></code><tt> </tt><code class=scheme><span class=selfeval>'non-terminating-macro</span></code><tt> </tt><code class=scheme><span class=variable>proc</span></code>
-- replaces the macro used to parse characters with no specific
mapping: i.e., characters (other than hash or vertical bar) that can
start a symbol or number with the default readtable.</p>
<p>
</p>
</ul><p>
If multiple <code class=scheme><span class=selfeval>'dispatch-macro</span></code> mappings are provided for a
single <code class=scheme><span class=variable>char-or-false</span></code>, all but the last one are
ignored. Similarly, if multiple non-<code class=scheme><span class=selfeval>'dispatch-macro</span></code> mappings
are provided for a single <code class=scheme><span class=variable>char-or-false</span></code>, all but the last one
are ignored.</p>
<p>
A reader macro <code class=scheme><span class=variable>proc</span></code> must accept six arguments, and it can
optionally accept two arguments. See section <a href="#node_sec_11.2.9">11.2.9</a> for
information on the procedure's arguments and results.</p>
<p>
A reader macro normally reads characters from the given input port to
produce a value to be used as the ``reader macro-expansion'' of the
consumed characters. The reader macro might produce a special-comment
value to cause the consumed character to be treated as whitespace,
and it might use <code class=scheme>read/recursive</code> or
<code class=scheme>read-syntax/recursive</code>; see section <a href="#node_sec_11.2.9.1">11.2.9.1</a> and
section <a href="#node_sec_11.2.9.2">11.2.9.2</a> for more information on these topics.</p>
<p>
<a name="node_idx_2452"></a><a name="node_kw_definitionreadtable-mapping"></a><code class=scheme>(readtable-mapping</code><tt> </tt><code class=scheme><span class=variable>readtable char</span></code><code class=scheme>)</code>, where <code class=scheme><span class=variable>readtable</span></code> is not
<code class=scheme><span class=selfeval>#f</span></code>, produces information about the mappings in
<code class=scheme><span class=variable>readtable</span></code> for <code class=scheme><span class=variable>char</span></code>. The result is three values:
</p>
<ul><p>
</p>
<li><p>either a character (mapping is to same behavior as the
character in the default readtable), <code class=scheme><span class=selfeval>'terminating-macro</span></code>, or
<code class=scheme><span class=selfeval>'non-terminating-macro</span></code>; this result reports the main (i.e.,
non-<code class=scheme><span class=selfeval>'dispatch-macro</span></code>) mapping for <code class=scheme><span class=variable>char</span></code>. When the result
is a character, then <code class=scheme><span class=variable>char</span></code> is mapped to the same behavior as the
returned character in the default readtable.</p>
<p>
</p>
<li><p>either <code class=scheme><span class=selfeval>#f</span></code> or a reader-macro procedure; the result is a
procedure when the first result is <code class=scheme><span class=selfeval>'terminating-macro</span></code> or
<code class=scheme><span class=selfeval>'non-terminating-macro</span></code>.</p>
<p>
</p>
<li><p>either <code class=scheme><span class=selfeval>#f</span></code> or a reader-macro procedure; the result is a
procedure when the character has a <code class=scheme><span class=selfeval>'dispatch-macro</span></code> mapping in
<code class=scheme><span class=variable>readtable</span></code> to override the default dispatch behavior.</p>
<p>
</p>
</ul><p>
Note that reader-macro procedures for the default readtable are not
directly accessible. To invoke default behaviors, use
<code class=scheme>read/recursive</code> or <code class=scheme>read-syntax/recursive</code> (see
section <a href="#node_sec_11.2.9.2">11.2.9.2</a>) with a character and the <code class=scheme><span class=selfeval>#f</span></code>
readtable.</p>
<p>
Extended example:
</p>
<div align=left><pre class=scheme><span class=comment>;; Provides <code class=scheme>raise-read-error</code> and <code class=scheme>raise-read-eof-error</code></span>
(<span class=keyword>require</span> (<span class=variable>lib</span> <span class=selfeval>"readerr.ss"</span> <span class=selfeval>"syntax"</span>))
(<span class=keyword>define</span> (<span class=variable>skip-whitespace</span> <span class=variable>port</span>)
<span class=comment>;; Skips whitespace characters, sensitive to the current</span>
<span class=comment>;; readtable's definition of whitespace</span>
(<span class=keyword>let</span> ([<span class=variable>ch</span> (<code class=scheme>peek-char</code> <span class=variable>port</span>)])
(<span class=keyword>unless</span> (<span class=variable>eof-object?</span> <span class=variable>ch</span>)
<span class=comment>;; Consult current readtable:</span>
(<span class=keyword>let-values</span> ([(<span class=variable>like-ch/sym</span> <span class=variable>proc</span> <span class=variable>dispatch-proc</span>)
(<span class=variable>readtable-mapping</span> (<code class=scheme>current-readtable</code>) <span class=variable>ch</span>)])
<span class=comment>;; If like-ch/sym is whitespace, then ch is whitespace</span>
(<span class=keyword>when</span> (<span class=keyword>and</span> (<span class=variable>char?</span> <span class=variable>like-ch/sym</span>)
(<code class=scheme>char-whitespace?</code> <span class=variable>like-ch/sym</span>))
(<code class=scheme>read-char</code> <span class=variable>port</span>)
(<span class=variable>skip-whitespace</span> <span class=variable>port</span>))))))
(<span class=keyword>define</span> (<span class=variable>skip-comments</span> <span class=variable>read-one</span> <span class=variable>port</span> <span class=variable>src</span>)
<span class=comment>;; Recursive read, but skip comments and detect EOF</span>
(<span class=keyword>let</span> <span class=variable>loop</span> ()
(<span class=keyword>let</span> ([<span class=variable>v</span> (<span class=variable>read-one</span>)])
(<span class=keyword>cond</span>
[(<span class=variable>special-comment?</span> <span class=variable>v</span>) (<span class=variable>loop</span>)]
[(<span class=variable>eof-object?</span> <span class=variable>v</span>)
(<span class=keyword>let-values</span> ([(<span class=variable>l</span> <span class=variable>c</span> <span class=variable>p</span>) (<code class=scheme>port-next-location</code> <span class=variable>port</span>)])
(<span class=variable>raise-read-eof-error</span> <span class=selfeval>"unexpected EOF in tuple"</span> <span class=variable>src</span> <span class=variable>l</span> <span class=variable>c</span> <span class=variable>p</span> <span class=selfeval>1</span>))]
[<span class=keyword>else</span> <span class=variable>v</span>]))))
(<span class=keyword>define</span> (<span class=variable>parse</span> <span class=variable>port</span> <span class=variable>read-one</span> <span class=variable>src</span>)
<span class=comment>;; First, check for empty tuple</span>
(<span class=variable>skip-whitespace</span> <span class=variable>port</span>)
(<span class=keyword>if</span> (<code class=scheme>eq?</code> <span class=selfeval>#\></span> (<code class=scheme>peek-char</code> <span class=variable>port</span>))
<code class=scheme>null</code>
(<span class=keyword>let</span> ([<span class=variable>elem</span> (<span class=variable>read-one</span>)])
(<span class=keyword>if</span> (<span class=variable>special-comment?</span> <span class=variable>elem</span>)
<span class=comment>;; Found a comment, so look for > again</span>
(<span class=variable>parse</span> <span class=variable>port</span> <span class=variable>read-one</span> <span class=variable>src</span>)
<span class=comment>;; Non-empty tuple:</span>
(<code class=scheme>cons</code> <span class=variable>elem</span>
(<span class=variable>parse-nonempty</span> <span class=variable>port</span> <span class=variable>read-one</span> <span class=variable>src</span>))))))
(<span class=keyword>define</span> (<span class=variable>parse-nonempty</span> <span class=variable>port</span> <span class=variable>read-one</span> <span class=variable>src</span>)
<span class=comment>;; Need a comma or closer</span>
(<span class=variable>skip-whitespace</span> <span class=variable>port</span>)
(<span class=keyword>case</span> (<code class=scheme>peek-char</code> <span class=variable>port</span>)
[(<span class=selfeval>#\></span>) (<code class=scheme>read-char</code> <span class=variable>port</span>)
<span class=comment>;; Done</span>
<code class=scheme>null</code>]
[(<span class=selfeval>#\,</span>) (<code class=scheme>read-char</code> <span class=variable>port</span>)
<span class=comment>;; Read next element and recur</span>
(<code class=scheme>cons</code> (<span class=variable>skip-comments</span> <span class=variable>read-one</span> <span class=variable>port</span> <span class=variable>src</span>)
(<span class=variable>parse-nonempty</span> <span class=variable>port</span> <span class=variable>read-one</span> <span class=variable>src</span>))]
[<span class=keyword>else</span>
<span class=comment>;; Either a comment or an error; grab location (in case</span>
<span class=comment>;; of error) and read recursively to detect comments</span>
(<span class=keyword>let-values</span> ([(<span class=variable>l</span> <span class=variable>c</span> <span class=variable>p</span>) (<code class=scheme>port-next-location</code> <span class=variable>port</span>)]
[(<span class=variable>v</span>) (<span class=variable>read-one</span>)])
(<span class=keyword>cond</span>
[(<span class=variable>special-comment?</span> <span class=variable>v</span>)
<span class=comment>;; It was a comment, so try again</span>
(<span class=variable>parse-nonempty</span> <span class=variable>port</span> <span class=variable>read-one</span> <span class=variable>src</span>)]
[<span class=keyword>else</span>
<span class=comment>;; Wasn't a comment, comma, or closer; error</span>
((<span class=keyword>if</span> (<span class=variable>eof-object?</span> <span class=variable>v</span>) <span class=variable>raise-read-eof-error</span> <span class=variable>raise-read-error</span>)
<span class=selfeval>"expected `,' or `>'"</span> <span class=variable>src</span> <span class=variable>l</span> <span class=variable>c</span> <span class=variable>p</span> <span class=selfeval>1</span>)]))]))
(<span class=keyword>define</span> (<span class=variable>make-delims-table</span>)
<span class=comment>;; Table to use for recursive reads to disallow delimiters</span>
<span class=comment>;; (except those in sub-expressions)</span>
(<span class=keyword>letrec</span> ([<span class=variable>misplaced-delimiter</span>
(<span class=keyword>case-lambda</span>
[(<span class=variable>ch</span> <span class=variable>port</span>) (<span class=variable>unexpected-delimiter</span> <span class=variable>ch</span> <span class=variable>port</span> <span class=selfeval>#f</span> <span class=selfeval>#f</span> <span class=selfeval>#f</span> <span class=selfeval>#f</span>)]
[(<span class=variable>ch</span> <span class=variable>port</span> <span class=variable>src</span> <span class=variable>line</span> <span class=variable>col</span> <span class=variable>pos</span>)
(<span class=variable>raise-read-error</span>
(<code class=scheme>format</code> <span class=selfeval>"misplaced `~a' in tuple"</span> <span class=variable>ch</span>) <span class=variable>src</span> <span class=variable>line</span> <span class=variable>col</span> <span class=variable>pos</span> <span class=selfeval>1</span>)])])
(<code class=scheme>make-readtable</code> (<code class=scheme>current-readtable</code>)
<span class=selfeval>#\,</span> <span class=keyword>'</span><span class=variable>terminating-macro</span> <span class=variable>misplaced-delimiter</span>
<span class=selfeval>#\></span> <span class=keyword>'</span><span class=variable>terminating-macro</span> <span class=variable>misplaced-delimiter</span>)))
(<span class=keyword>define</span> (<span class=variable>wrap</span> <span class=variable>l</span>)
<span class=keyword>`</span>(<span class=variable>make-tuple</span> (<code class=scheme>list</code> <span class=keyword>,@</span><span class=variable>l</span>)))
(<span class=keyword>define</span> <span class=variable>parse-open-tuple</span>
(<span class=keyword>case-lambda</span>
[(<span class=variable>ch</span> <span class=variable>port</span>)
<span class=comment>;; `read' mode</span>
(<span class=variable>wrap</span> (<span class=variable>parse</span> <span class=variable>port</span>
(<span class=keyword>lambda</span> () (<code class=scheme>read/recursive</code> <span class=variable>port</span> <span class=selfeval>#f</span>
(<span class=variable>make-delims-table</span>)))
(<code class=scheme>object-name</code> <span class=variable>port</span>)))]
[(<span class=variable>ch</span> <span class=variable>port</span> <span class=variable>src</span> <span class=variable>line</span> <span class=variable>col</span> <span class=variable>pos</span>)
<span class=comment>;; `read-syntax' mode</span>
(<code class=scheme>datum->syntax-object</code>
<span class=selfeval>#f</span>
(<span class=variable>wrap</span> (<span class=variable>parse</span> <span class=variable>port</span>
(<span class=keyword>lambda</span> () (<code class=scheme>read-syntax/recursive</code> <span class=variable>src</span> <span class=variable>port</span> <span class=selfeval>#f</span>
(<span class=variable>make-delims-table</span>)))
<span class=variable>src</span>))
(<span class=keyword>let-values</span> ([(<span class=variable>l</span> <span class=variable>c</span> <span class=variable>p</span>) (<code class=scheme>port-next-location</code> <span class=variable>port</span>)])
(<code class=scheme>list</code> <span class=variable>src</span> <span class=variable>line</span> <span class=variable>col</span> <span class=variable>pos</span> (<span class=keyword>and</span> <span class=variable>pos</span> (<span class=variable>-</span> <span class=variable>p</span> <span class=variable>pos</span>)))))]))
(<span class=keyword>define</span> <span class=variable>tuple-readtable</span>
(<code class=scheme>make-readtable</code> <span class=selfeval>#f</span> <span class=selfeval>#\<</span> <span class=keyword>'</span><span class=variable>terminating-macro</span> <span class=variable>parse-open-tuple</span>))
(<span class=keyword>parameterize</span> ([<code class=scheme>current-readtable</code> <span class=variable>tuple-readtable</span>])
(<code class=scheme>read</code> (<code class=scheme>open-input-string</code> <span class=selfeval>"<1 , 2 , \"a\">"</span>)))
<span class=comment>;; => <code class=schemeresponse><span class=keyword>'</span>(<span class=variable>make-tuple</span> (<code class=scheme>list</code> <span class=selfeval>1</span> <span class=selfeval>2</span> <span class=selfeval>"a"</span>))</code></span>
(<span class=keyword>parameterize</span> ([<code class=scheme>current-readtable</code> <span class=variable>tuple-readtable</span>])
(<code class=scheme>read</code> (<code class=scheme>open-input-string</code> <span class=selfeval>"< #||# 1 #||# , #||# 2 #||# , #||# \"a\" #||# >"</span>)))
<span class=comment>;; => <code class=schemeresponse><span class=keyword>'</span>(<span class=variable>make-tuple</span> (<code class=scheme>list</code> <span class=selfeval>1</span> <span class=selfeval>2</span> <span class=selfeval>"a"</span>))</code></span>
(<span class=keyword>define</span> <span class=variable>tuple-readtable+</span>
(<code class=scheme>make-readtable</code> <span class=variable>tuple-readtable</span>
<span class=selfeval>#\*</span> <span class=keyword>'</span><span class=variable>terminating-macro</span> (<span class=keyword>lambda</span> <span class=variable>a</span> (<span class=variable>make-special-comment</span> <span class=selfeval>#f</span>))
<span class=selfeval>#\_</span> <span class=selfeval>#\space</span> <span class=selfeval>#f</span>))
(<span class=keyword>parameterize</span> ([<code class=scheme>current-readtable</code> <span class=variable>tuple-readtable+</span>])
(<code class=scheme>read</code> (<code class=scheme>open-input-string</code> <span class=selfeval>"< * 1 __,__ 2 __,__ * \"a\" * >"</span>)))
<span class=comment>;; => <code class=schemeresponse><span class=keyword>'</span>(<span class=variable>make-tuple</span> (<code class=scheme>list</code> <span class=selfeval>1</span> <span class=selfeval>2</span> <span class=selfeval>"a"</span>))</code></span>
</pre></div><p></p>
<p>
</p>
<a name="node_sec_11.2.9"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.9">11.2.9 Reader-Extension Procedures</a></h3>
<p></p>
<p>
MzScheme's reader can be extended in three ways: through a
reader-macro procedure in a readtable (see section <a href="#node_sec_11.2.8">11.2.8</a>),
through a <code class=scheme>#reader</code> form (see section <a href="#node_sec_11.2.4">11.2.4</a>), or through a
custom-port byte reader that returns a ``special'' result procedure
(see section <a href="#node_sec_11.1.7.1">11.1.7.1</a>). All three kinds of procedures accept
similar arguments, and their results are treated in the same way by
<code class=scheme>read</code> and <code class=scheme>read-syntax</code> (or, more precisely, by the
default read handler; see section <a href="#node_sec_11.2.6">11.2.6</a>).</p>
<p>
Calls to these reader-extension procedures can be triggered through
<code class=scheme>read</code>, <code class=scheme>read/recursive</code>, <code class=scheme>read-syntax</code>, or
<code class=scheme>read-honu-syntax</code>. In addition, a special-read procedure can
be triggered by calls to <code class=scheme>read-honu</code>,
<code class=scheme>read-honu/recursive</code>, <code class=scheme>read-honu-syntax</code>,
<code class=scheme>read-honu-syntax/recursive</code>, <code class=scheme>read-char-or-special</code>,
or by the context of <code class=scheme>read-bytes-avail!</code>,
<code class=scheme>read-bytes-avail!*</code>, <code class=scheme>read-bytes-avail!</code>, and
<code class=scheme>peek-bytes-avail!*</code>.</p>
<p>
Optional arities for reader-macro and special-result procedures allow
them to distinguish reads via <code class=scheme>read</code>, etc. from reads via
<code class=scheme>read-syntax</code>, etc. in the case that the source value is
<code class=scheme><span class=selfeval>#f</span></code> and no other location information is available.</p>
<p>
<strong>Procedure arguments</strong></p>
<p>
A reader-macro procedure must accept six arguments, and it can
optionally accept two arguments. The first two arguments are always
the character that triggered the reader macro and the input port for
reading. When the reader macro is triggered by <code class=scheme>read-syntax</code>
(or <code class=scheme>read-syntax/recursive</code>), the procedure is passed four
additional arguments that represent a source location. When the
reader macro is triggered by <code class=scheme>read</code> (or
<code class=scheme>read/recursive</code>), the procedure is passed only two arguments
if it accepts two arguments, otherwise it is passed six arguments
where the last four are all <code class=scheme><span class=selfeval>#f</span></code>.</p>
<p>
A <code class=scheme>#reader</code>-loaded procedure accepts the same arguments as
either <code class=scheme>read</code> or <code class=scheme>read-syntax</code>, depending on whether
the procedure was loaded through <code class=scheme>read</code>, etc. or through
<code class=scheme>read-syntax</code>, etc.</p>
<p>
A special-result procedure must accept four arguments, and it can
optionally accept zero arguments. When the special read is triggered
by <code class=scheme>read-syntax</code> (or <code class=scheme>read-honu-syntax</code>,
<code class=scheme>read-syntax/recursive</code>, etc.), the procedure is passed four
arguments that represent a source location. When the special read is
triggered by <code class=scheme>read</code> (or <code class=scheme>read-char-or-special</code>,
<code class=scheme>read-honu</code>, <code class=scheme>read/syntax</code>, etc.), the procedure is
passed no arguments if it accepts zero arguments, otherwise it is
passed four arguments that are all <code class=scheme><span class=selfeval>#f</span></code>.</p>
<p>
<strong>Procedure result</strong></p>
<p>
When a reader-extension procedure is called in syntax-reading mode
(via <code class=scheme>read-syntax</code>, etc.), it should generally return a syntax
object that has no lexical context (e.g., a syntax object created
using <code class=scheme><code class=scheme>datum->syntax-object</code></code> with <code class=scheme><span class=selfeval>#f</span></code> as the first
argument and with the given location information as the third
argument). Another possible result is a special-comment value (see
section <a href="#node_sec_11.2.9.1">11.2.9.1</a>). If the procedure's result is not a syntax
object and not a special-comment value, it is converted to one using
<code class=scheme><code class=scheme>datum->syntax-object</code></code>.</p>
<p>
When a reader-extension procedure is called in non-syntax-reading
modes, it should generally not return a syntax object. If a syntax
object is returned, it is converted to a plain value using
<code class=scheme><code class=scheme>syntax-object->datum</code></code>.</p>
<p>
In either context, when the result from a reader-extension procedure
is a special-comment value (see section <a href="#node_sec_11.2.9.1">11.2.9.1</a>), then
<code class=scheme>read</code>, <code class=scheme>read-syntax</code>, etc. treat the value as a
delimiting comment and otherwise ignore it.</p>
<p>
Also in either context, the result may be copied to prevent mutation
to pairs, vectors, or boxes before the read result is completed, and
to support the construction of graphs with cycles. Mutable pairs,
boxes, and vectors are copied, along with any pairs, boxes, or
vectors that lead to such mutable values, to placeholders produced by
a recursive read (see section <a href="#node_sec_11.2.9.2">11.2.9.2</a>), or to references of
a shared value. Graph structure (including cycles) is preserved in
the copy.</p>
<p>
</p>
<a name="node_sec_11.2.9.1"></a>
<h4><a href="mzscheme.html#node_toc_node_sec_11.2.9.1">11.2.9.1 Special Comments</a></h4>
<p></p>
<p>
<a name="node_idx_2454"></a><a name="node_kw_definitionmake-special-comment"></a><code class=scheme>(make-special-comment</code><tt> </tt><code class=scheme><span class=variable>v</span></code><code class=scheme>)</code> creates a special-comment value that
encapsulates <code class=scheme><span class=variable>v</span></code>. The <code class=scheme>read</code>, <code class=scheme>read-syntax</code>, etc.
procedures treat values constructed with
<code class=scheme>make-special-comment</code> as delimiting whitespace when returned
by a reader-extension procedure (see section <a href="#node_sec_11.2.9">11.2.9</a>).</p>
<p>
<a name="node_idx_2456"></a><a name="node_kw_definitionspecial-comment_Q_"></a><code class=scheme>(special-comment?</code><tt> </tt><code class=scheme><span class=variable>v</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if
<code class=scheme><span class=variable>v</span></code> is the result of <code class=scheme>make-special-comment</code>, <code class=scheme><span class=selfeval>#f</span></code>
otherwise.</p>
<p>
<a name="node_idx_2458"></a><a name="node_kw_definitionspecial-comment-value"></a><code class=scheme>(special-comment-value</code><tt> </tt><code class=scheme><span class=variable>sc</span></code><code class=scheme>)</code> returns the value encapsulated by the
special-comment value <code class=scheme><span class=variable>sc</span></code>. This value is never used directly by
a reader, but it might be used by the context of a
<code class=scheme>read-char-or-special</code>, etc. call that detects a special
comment.</p>
<p>
</p>
<a name="node_sec_11.2.9.2"></a>
<h4><a href="mzscheme.html#node_toc_node_sec_11.2.9.2">11.2.9.2 Recursive Reads</a></h4>
<p></p>
<p>
<a name="node_idx_2460"></a><a name="node_kw_definitionread/recursive"></a><code class=scheme>(read/recursive</code><tt> </tt>[<code class=scheme><span class=variable>input-port char-or-false readtable</span></code>]<code class=scheme>)</code> is similar
to calling <code class=scheme><code class=scheme>read</code></code>, but it is normally used during the dynamic
extent of <code class=scheme>read</code> within a reader-extension procedure (see
section <a href="#node_sec_11.2.9">11.2.9</a>). The main effect of using
<code class=scheme>read/recursive</code> instead of <code class=scheme>read</code> is that
graph-structure annotations (see section <a href="#node_sec_11.2.5.1">11.2.5.1</a>) in the nested
read are considered part of the overall read. Since the result is wrapped in a
placeholder, however, it is not directly inspectable.</p>
<p>
If <code class=scheme><span class=variable>char-or-false</span></code> is provided and not <code class=scheme><span class=selfeval>#f</span></code>, it is
effectively prefixed to the beginning of <code class=scheme><span class=variable>input-port</span></code>'s stream
for the read. (To prefix multiple characters, use
<code class=scheme>input-port-append</code> from MzLib's <tt><strong>port</strong></tt> library; see
Chapter <a href="../mzlib/mzlib-Z-H-32.html#node_chap_32">32</a>
in <a href="../mzlib/mzlib.html"><i>PLT MzLib: Libraries Manual</i></a>.)</p>
<p>
The <code class=scheme><span class=variable>readtable</span></code> argument, which defaults to
<code class=scheme>(current-readtable)</code>, is used for top-level parsing to
satisfy the read request; recursive parsing within the read (e.g., to
read the elements of a list) instead uses the current readtable as
determined by the <code class=scheme>current-readtable</code> parameter. A reader
macro might call <code class=scheme>read/recursive</code> with a character and
readtable to effectively invoke the readtable's behavior for the
character. If <code class=scheme><span class=variable>readtable</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, the default readtable
is used for top-level parsing.</p>
<p>
When called within the dynamic extent of <code class=scheme>read</code>, the
<code class=scheme>read/recursive</code> procedure produces either an opaque
placeholder value, a special-comment value, or an end-of-file. The
result is a special-comment value (see section <a href="#node_sec_11.2.9.1">11.2.9.1</a>)
when the input stream's first non-whitespace content parses as a
comment. The result is end-of-file when <code class=scheme>read/recursive</code>
encounters an end-of-file. Otherwise, the result is a placeholder
that protects graph references that are not yet resolved. When this
placeholder is returned within an S-expression that is produced by
any reader-extension procedure (see section <a href="#node_sec_11.2.9">11.2.9</a>) for the
same outermost <code class=scheme><code class=scheme>read</code></code>, it will be replaced with the actual
read value before the outermost <code class=scheme>read</code> returns.</p>
<p>
<a name="node_idx_2462"></a><a name="node_kw_definitionread-syntax/recursive"></a><code class=scheme>(read-syntax/recursive</code><tt> </tt>[<code class=scheme><span class=variable>source-name-v input-port char-or-false readtable</span></code>]<code class=scheme>)</code>
is analogous to calling <code class=scheme>read/recursive</code>, but the resulting
value encapsulates S-expression structure with source-location
information. As with <code class=scheme>read/recursive</code>, when
<code class=scheme>read-syntax/recursive</code> is used within the dynamic extent of
<code class=scheme>read-syntax</code>, the result of from
<code class=scheme>read-syntax/recursive</code> is either a special-comment value,
end-of-file, or opaque graph-structure
placeholder (not a syntax object). The placeholder can be embedded
in an S-expression or syntax object returned by a reader macro, etc.,
and it will be replaced with the actual syntax object before the
outermost <code class=scheme>read-syntax</code> returns.</p>
<p>
Using <code class=scheme>read/recursive</code> within the dynamic extent of
<code class=scheme>read-syntax</code> does not allow graph structure for reading to be
included in the outer <code class=scheme>read-syntax</code> parsing, and neither does
using <code class=scheme>read-syntax/recursive</code> within the dynamic extent of
<code class=scheme>read</code>. In those cases, <code class=scheme>read/recursive</code> and
<code class=scheme>read-syntax/recursive</code> produce results like <code class=scheme>read</code> and
<code class=scheme>read-syntax</code>.</p>
<p>
See section <a href="#node_sec_11.2.8">11.2.8</a> for an extended example that uses
<code class=scheme>read/recursive</code> and <code class=scheme>read-syntax/recursive</code>.</p>
<p>
</p>
<a name="node_sec_11.2.10"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.2.10">11.2.10 Customizing the Printer through Custom-Write Procedures</a></h3>
<p></p>
<p>
The built-in
<a name="node_kw_definitionprop_C_custom-write"></a><code class=scheme>prop:custom-write</code>
structure type property associates a procedures to a structure
type. The procedure is used by the default printer to
<code class=scheme>display</code> or <code class=scheme>write</code> (or <code class=scheme>print</code>) instances of
the structure type.</p>
<p>
See section <a href="mzscheme-Z-H-4.html#node_sec_4.4">4.4</a> for general information on structure type
properties.</p>
<p>
The procedure for a <code class=scheme>prop:custom-write</code> value takes three
arguments: the structure to be printed, the target port, and a
boolean that is <code class=scheme><span class=selfeval>#t</span></code> for <code class=scheme>write</code> mode and <code class=scheme><span class=selfeval>#f</span></code>
for <code class=scheme>display</code> mode. The procedure should print the value to
the given port using <code class=scheme>write</code>, <code class=scheme>display</code>,
<code class=scheme>fprintf</code>, <code class=scheme>write-special</code>, etc.</p>
<p>
The write handler, display handler, and print handler are specially
configured for a port given to a custom-write procedure. Printing to
the port through <code class=scheme>display</code>, <code class=scheme>write</code>, or <code class=scheme>print</code>
prints a value recursively with sharing annotations. To avoid a
recursive print (i.e., to print without regard to sharing with a
value currently being printed), print instead to a string or pipe and
transfer the result to the target port using <code class=scheme>write-string</code>
and <code class=scheme>write-special</code>. To recursively print but to a port other
than the one given to the custom-write procedure, copy the given
port's write handler, display handler, and print handler to the other
port.</p>
<p>
The port given to a custom-write handler is not necessarily the actual
target port. In particular, to detect cycles and sharing, the printer
invokes a custom-write procedure with a port that records recursive
prints, and does not retain any other output.</p>
<p>
Recursive print operations may trigger an escape from the call to the
custom-write procedure (e.g., for pretty-printing where a tentative
print attempt overflows the line, or for printing error output of a
limited width).</p>
<p>
The following example definition of a <code class=scheme><span class=variable>tuple</span></code> type includes
custom-write procedures that print the tuple's list content using
angle brackets in <code class=scheme><code class=scheme>write</code></code> mode and no brackets in
<code class=scheme><code class=scheme>display</code></code> mode. Elements of the tuple are printed recursively,
so that graph and cycle structure can be represented.
</p>
<div align=left><pre class=scheme>(<span class=keyword>define</span> (<span class=variable>tuple-print</span> <span class=variable>tuple</span> <span class=variable>port</span> <span class=variable>write?</span>)
(<span class=keyword>when</span> <span class=variable>write?</span> (<span class=variable>write-string</span> <span class=selfeval>"<"</span> <span class=variable>port</span>))
(<span class=keyword>let</span> ([<span class=variable>l</span> (<span class=variable>tuple-ref</span> <span class=variable>tuple</span> <span class=selfeval>0</span>)])
(<span class=keyword>unless</span> (<code class=scheme>null?</code> <span class=variable>l</span>)
((<span class=keyword>if</span> <span class=variable>write?</span> <code class=scheme>write</code> <code class=scheme>display</code>) (<code class=scheme>car</code> <span class=variable>l</span>) <span class=variable>port</span>)
(<code class=scheme>for-each</code> (<span class=keyword>lambda</span> (<code class=scheme>e</code>)
(<span class=variable>write-string</span> <span class=selfeval>", "</span> <span class=variable>port</span>)
((<span class=keyword>if</span> <span class=variable>write?</span> <code class=scheme>write</code> <code class=scheme>display</code>) <code class=scheme>e</code> <span class=variable>port</span>))
(<code class=scheme>cdr</code> <span class=variable>l</span>))))
(<span class=keyword>when</span> <span class=variable>write?</span> (<span class=variable>write-string</span> <span class=selfeval>">"</span> <span class=variable>port</span>)))
(<span class=keyword>define-values</span> (<span class=variable>s:tuple</span> <span class=variable>make-tuple</span> <span class=variable>tuple?</span> <span class=variable>tuple-ref</span> <span class=variable>tuple-set!</span>)
(<code class=scheme>make-struct-type</code> <span class=keyword>'</span><span class=variable>tuple</span> <span class=selfeval>#f</span> <span class=selfeval>1</span> <span class=selfeval>0</span> <span class=selfeval>#f</span>
(<code class=scheme>list</code> (<code class=scheme>cons</code> <span class=variable>prop:custom-write</span> <span class=variable>tuple-print</span>))))
(<code class=scheme>display</code> (<span class=variable>make-tuple</span> <span class=keyword>'</span>(<span class=selfeval>1</span> <span class=selfeval>2</span> <span class=selfeval>"a"</span>))) <span class=comment>; prints <code class=schemeresponse><span class=selfeval>1</span><span class=keyword>,</span> <span class=selfeval>2</span><span class=keyword>,</span> <span class=variable>a</span></code></span>
(<span class=keyword>let</span> ([<span class=variable>t</span> (<span class=variable>make-tuple</span> (<code class=scheme>list</code> <span class=selfeval>1</span> <span class=selfeval>2</span> <span class=selfeval>"a"</span>))])
(<code class=scheme>set-car!</code> (<span class=variable>tuple-ref</span> <span class=variable>t</span> <span class=selfeval>0</span>) <span class=variable>t</span>)
(<code class=scheme>write</code> <span class=variable>t</span>)) <span class=comment>; prints <code class=schemeresponse><span class=selfeval>#0=<#0#</span><span class=keyword>,</span> <span class=selfeval>2</span><span class=keyword>,</span> <span class=selfeval>"a"</span><span class=variable>></span></code></span>
</pre></div><p></p>
<p>
</p>
<a name="node_sec_11.3"></a>
<h2><a href="mzscheme.html#node_toc_node_sec_11.3">11.3 Filesystem Utilities</a></h2>
<p><a name="node_idx_2464"></a></p>
<p>
MzScheme provides many operations for accessing and modifying
filesystems in a (mostly) platform-independent manner. Additional
filesystem utilities are in MzLib; see also Chapter <a href="../mzlib/mzlib-Z-H-17.html#node_chap_17">17</a>
in <a href="../mzlib/mzlib.html"><i>PLT MzLib: Libraries Manual</i></a>.</p>
<p>
</p>
<a name="node_sec_11.3.1"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.3.1">11.3.1 Paths</a></h3>
<p></p>
<p>
<a name="node_idx_2466"></a>
<a name="node_idx_2468"></a>
The format of a filesystem path varies across platforms. For example,
under Unix, directories are separated by ``/'' while Windows uses
both ``/'' and ``<tt>\</tt>''. (See section <a href="mzscheme-Z-H-20.html#node_chap_20">20</a> for more
information on Windows paths in MzScheme.) Furthermore, for most Unix
filesystems, the true name of a file is a byte string, but users
prefer to see the bytes decoded in a locale-specific way when the
filename is printed. MzScheme therefore provides a <code class=scheme>path</code>
datatype for managing filesystem paths, and procedures such
as <code class=scheme>build-path</code>, <code class=scheme>path->string</code>,
and <code class=scheme>bytes->path</code> for manipulating paths. Two paths
are <code class=scheme><code class=scheme>equal?</code></code> when their byte-string representations
are <code class=scheme><code class=scheme>equal?</code></code>.</p>
<p>
When a MzScheme procedure takes a filesystem path as an argument, the
path can be provided either as a string or as an instance of the
<code class=scheme>path</code> datatype. If a string is provided, it is converted to a
path using <code class=scheme>string->path</code>. A MzScheme procedure that generates
a filesystem path always generates a <code class=scheme>path</code> value.</p>
<p>
<a name="node_idx_2470"></a>
Most MzScheme primitives that take path perform an expansion on the
path before using it. (Procedures that build paths or merely check
the form of a path do not perform this expansion.) Under Unix and Mac OS X,
a user directory specification using ``~'' is expanded and
multiple adjacent slashes are replaced with a single
slash.<a name="node_call_footnote_35"></a><a href="#node_footnote_35"><sup><small>35</small></sup></a> Under Windows, paths that
start <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt>, certain redundant
backslashes are removed; see section <a href="mzscheme-Z-H-20.html#node_chap_20">20</a> for more
information. Under Windows for other paths, multiple slashes are
converted to single slashes (except at the beginning of a shared
folder name), a slash is inserted after the colon in a drive
specification if it is missing, and trailing spaces and periods are
removed from the last path element unless that element consists of
only spaces and periods.</p>
<p>
A path string (or byte string) cannot be empty, and it cannot contain a nul
character or byte. When an empty string or a string containing nul is
provided as a path to any procedure except <code class=scheme><code class=scheme>absolute-path?</code></code>,
<code class=scheme><code class=scheme>relative-path?</code></code>, or <code class=scheme><code class=scheme>complete-path?</code></code> the
<a name="node_idx_2472"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
The basic path utilities are as follows:</p>
<p>
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2474"></a><a name="node_kw_definitionpath_Q_"></a><code class=scheme>(path?</code><tt> </tt><code class=scheme><span class=variable>v</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>v</span></code> is a path value
(not a string), <code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
</p>
<li><p><a name="node_idx_2476"></a><a name="node_kw_definitionpath-string_Q_"></a><code class=scheme>(path-string?</code><tt> </tt><code class=scheme><span class=variable>v</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>v</span></code> is either a
path value or a non-empty string without nul characters, <code class=scheme><span class=selfeval>#f</span></code>
otherwise.</p>
<p>
</p>
<li><p><a name="node_idx_2478"></a><a name="node_kw_definitionstring->path"></a><code class=scheme>(string->path</code><tt> </tt><code class=scheme><span class=variable>string</span></code><code class=scheme>)</code> produces a path whose byte-string
name is <code class=scheme>(<code class=scheme>string->bytes/locale</code> <span class=variable>string</span> (<code class=scheme>char->integer</code> <span class=selfeval>#\?</span>))</code>;
see section <a href="mzscheme-Z-H-3.html#node_sec_3.6">3.6</a> for more information on
<code class=scheme><code class=scheme>string->bytes/locale</code></code>. Beware that the current locale might
not encode every string, in which case <code class=scheme><span class=variable>string->path</span></code> can
produce the same path for different <code class=scheme><span class=variable>string</span></code>s.</p>
<p>
</p>
<li><p><a name="node_idx_2480"></a><a name="node_kw_definitionbytes->path"></a><code class=scheme>(bytes->path</code><tt> </tt><code class=scheme><span class=variable>bytes</span></code><code class=scheme>)</code> produces a path whose byte-string name
is <code class=scheme><span class=variable>bytes</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2482"></a><a name="node_kw_definitionpath->string"></a><code class=scheme>(path->string</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> produces a string that
represents <code class=scheme><span class=variable>path</span></code> by decoding <code class=scheme><span class=variable>path</span></code>'s byte-string name using
the current locale's encoding; ``?'' is used in the result string
where encoding fails, and if the encoding result is the empty string,
then the result is <code class=scheme><span class=selfeval>"?"</span></code>. In addition, under Windows, if the
path is relative and the byte-string version of the path starts
with <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt>REL</strong></tt>, this prefix and
the immediately following backslashes (one or two) are removed from
the resulting string. The resulting string is suitable for displaying
to a user, string-ordering comparisons, etc., but it is not suitable
for re-creating the path through <code class=scheme>string->path</code>, since
decoding and re-encoding the path's byte string may lose information.</p>
<p>
</p>
<li><p><a name="node_idx_2484"></a><a name="node_kw_definitionpath->bytes"></a><code class=scheme>(path->bytes</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> produces <code class=scheme><span class=variable>path</span></code>'s byte string
representation. No information is lost in this translation, so that
<code class=scheme>(<code class=scheme>bytes->path</code> (<code class=scheme>path->bytes</code> <span class=variable>path</span>))</code> always produces a path is
that is <code class=scheme><code class=scheme>equal?</code></code> to <code class=scheme><span class=variable>path</span></code>. For any reasonable locale,
consecutive ASCII characters in the printed form of <code class=scheme><span class=variable>path</span></code> are
mapped to consecutive byte values in <code class=scheme><span class=variable>path</span></code> that match each
character's code-point value, and a leading or trailing ASCII
character is mapped to a leading or trailing byte, respectively.</p>
<p>
</p>
<li><p><a name="node_idx_2486"></a><a name="node_kw_definitionbuild-path"></a><code class=scheme>(build-path</code><tt> </tt><code class=scheme><span class=variable>base-path sub-path</span></code><tt> </tt><tt>···</tt><code class=scheme>)</code> creates a path given a
base path and any number of sub-path extensions. If <code class=scheme><span class=variable>base-path</span></code>
is an absolute path, the result is an absolute path; if <code class=scheme><span class=variable>base</span></code> is
a relative path, the result is a relative path. Each <code class=scheme><span class=variable>sub-path</span></code>
must be either a relative path, a directory name, the
symbol <code class=scheme><span class=selfeval>'up</span></code><a name="node_idx_2488"></a> (indicating the relative parent directory),
or the symbol <code class=scheme><span class=selfeval>'same</span></code><a name="node_idx_2490"></a> (indicating the relative current
directory). Under Windows, if <code class=scheme><span class=variable>base-path</span></code> is a drive
specification (with or without a trailing slash) the
first <code class=scheme><span class=variable>sub-path</span></code> can be an absolute (driveless) path. The
last <code class=scheme><span class=variable>sub-path</span></code> can be a filename.</p>
<p>
Under Windows, trailing spaces and periods are removed from the last
element of <code class=scheme><span class=variable>base-path</span></code> and all but the last <code class=scheme><span class=variable>sub-path</span></code>
(unless the element consists of only spaces and peroids), except for
those that start
with <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt>. If <code class=scheme><span class=variable>base-path</span></code>
starts <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt>, then after each
non-<tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt>REL<tt>\</tt></strong></tt> <code class=scheme><span class=variable>sub-path</span></code>
is added, all slashes in the addition are converted to backslashes,
multiple consecutive backslashes are converted to a single backslash,
added <tt><strong>.</strong></tt> elements are removed, and added <tt><strong>..</strong></tt> elements are
removed along with the preceding element; these conversions are not
performed on the original <code class=scheme><span class=variable>base-path</span></code> part of the result or on
any <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt>REL<tt>\</tt></strong></tt> <code class=scheme><span class=variable>sub-path</span></code>.
In other cases under Windows, a backslash may be added or removed
before combining paths to avoid changing the root meaning of the path
(e.g., combining <tt><strong>//x</strong></tt> and <tt><strong>y</strong></tt> produces <tt><strong>/x/y</strong></tt>, because
<tt><strong>//x/y</strong></tt> would be a UNC path instead of a drive-relative path).</p>
<p>
Each <code class=scheme><span class=variable>sub-path</span></code> and <code class=scheme><span class=variable>base-path</span></code> can optionally end in a
directory separator. If the last <code class=scheme><span class=variable>sub-path</span></code> ends in a separator,
it is included in the resulting path.</p>
<p>
If <code class=scheme><span class=variable>base-path</span></code> or <code class=scheme><span class=variable>sub-path</span></code> is an illegal path string
(because it is empty or contains a nul character),
the <a name="node_idx_2492"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
The <code class=scheme><code class=scheme>build-path</code></code> procedure builds a path <em>without</em> checking
the validity of the path or accessing the filesystem.</p>
<p>
The following examples assume that the current directory
is <tt><strong>/home/joeuser</strong></tt> for Unix examples
and <tt><strong>C:<tt>\</tt>Joe's Files</strong></tt> for Windows examples.</p>
<p>
</p>
<div align=center><table><tr><td>
</td><td><div align=left><pre class=scheme>(<span class=keyword>define</span> <span class=variable>p1</span> (<code class=scheme>build-path</code> (<code class=scheme>current-directory</code>) <span class=selfeval>"src"</span> <span class=selfeval>"scheme"</span>))
<span class=comment>; Unix: p1 => <code class=schemeresponse><span class=selfeval>"/home/joeuser/src/scheme"</span></code></span>
<span class=comment>; Windows: p1 => <code class=schemeresponse><span class=selfeval>"C:\Joe's Files\src\scheme"</span></code></span>
(<span class=keyword>define</span> <span class=variable>p2</span> (<code class=scheme>build-path</code> <span class=keyword>'</span><span class=variable>up</span> <span class=keyword>'</span><span class=variable>up</span> <span class=selfeval>"docs"</span> <span class=selfeval>"MzScheme"</span>))
<span class=comment>; Unix: p2 => <code class=schemeresponse><span class=selfeval>"../../docs/MzScheme"</span></code></span>
<span class=comment>; Windows: p2 => <code class=schemeresponse><span class=selfeval>"..\..\docs\MzScheme"</span></code></span>
(<code class=scheme>build-path</code> <span class=variable>p2</span> <span class=variable>p1</span>)
<span class=comment>; Unix and Windows: raises <code class=scheme>exn:fail:contract</code> because <code class=scheme><span class=variable>p1</span></code> is absolute </span>
(<code class=scheme>build-path</code> <span class=variable>p1</span> <span class=variable>p2</span>)
<span class=comment>; Unix: => <code class=schemeresponse><span class=selfeval>"/home/joeuser/src/scheme/../../docs/MzScheme"</span></code></span>
<span class=comment>; Windows: => <code class=schemeresponse><span class=selfeval>"C:\Joe's Files\src\scheme\..\..\docs\MzScheme"</span></code></span>
</pre></div></td><td>
</td></tr></table></div>
<p>
</p>
<li><p><a name="node_idx_2494"></a><a name="node_kw_definitionabsolute-path_Q_"></a><code class=scheme>(absolute-path?</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>path</span></code> is an
absolute path, <code class=scheme><span class=selfeval>#f</span></code> otherwise. If <code class=scheme><span class=variable>path</span></code> is not a legal
path string (e.g., it contains a nul character), <code class=scheme><span class=selfeval>#f</span></code> is
returned. This procedure does not access the filesystem.</p>
<p>
</p>
<li><p><a name="node_idx_2496"></a><a name="node_kw_definitionrelative-path_Q_"></a><code class=scheme>(relative-path?</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>path</span></code> is a
relative path, <code class=scheme><span class=selfeval>#f</span></code> otherwise. If <code class=scheme><span class=variable>path</span></code> is not a legal
path string (e.g., it contains a nul character), <code class=scheme><span class=selfeval>#f</span></code> is
returned. This procedure does not access the filesystem.</p>
<p>
</p>
<li><p><a name="node_idx_2498"></a><a name="node_kw_definitioncomplete-path_Q_"></a><code class=scheme>(complete-path?</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>path</span></code> is
a completely determined path (<em>not</em> relative to a directory or
drive), <code class=scheme><span class=selfeval>#f</span></code> otherwise. Note that under Windows, an absolute
path can omit the drive specification, in which case the path is
neither relative nor complete. If <code class=scheme><span class=variable>path</span></code> is not a legal path
string (e.g., it contains a nul character), <code class=scheme><span class=selfeval>#f</span></code> is
returned. This procedure does not access the filesystem.</p>
<p>
</p>
<li><p><a name="node_idx_2500"></a><a name="node_kw_definitionpath->complete-path"></a><code class=scheme>(path->complete-path</code><tt> </tt><code class=scheme><span class=variable>path</span></code><tt> </tt>[<code class=scheme><span class=variable>base-path</span></code>]<code class=scheme>)</code> returns <code class=scheme><span class=variable>path</span></code>
as a complete path. If <code class=scheme><span class=variable>path</span></code> is already a complete path, it is
returned as the result. Otherwise, <code class=scheme><span class=variable>path</span></code> is resolved with
respect to the complete path <code class=scheme><span class=variable>base-path</span></code>. If <code class=scheme><span class=variable>base-path</span></code> is
omitted, <code class=scheme><span class=variable>path</span></code> is resolved with respect to the current
directory. If <code class=scheme><span class=variable>base-path</span></code> is provided and it is not a complete
path, the <a name="node_idx_2502"></a><code class=scheme>exn:fail:contract</code> exception is raised. This procedure does not
access the filesystem.</p>
<p>
</p>
<li><p><a name="node_idx_2504"></a><a name="node_kw_definitionresolve-path"></a><code class=scheme>(resolve-path</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> expands <code class=scheme><span class=variable>path</span></code> and returns a
path that references the same file or directory as
<code class=scheme><span class=variable>path</span></code>. Under Unix and Mac OS X, if <code class=scheme><span class=variable>path</span></code> is a soft link to
another path, then the referenced path is returned (this may
be a relative path with respect to the directory
owning <code class=scheme><span class=variable>path</span></code>) otherwise <code class=scheme><span class=variable>path</span></code> is returned (after expansion).</p>
<p>
</p>
<li><p><a name="node_idx_2506"></a><a name="node_kw_definitionexpand-path"></a><code class=scheme>(expand-path</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> returns the expanded version of
<code class=scheme><span class=variable>path</span></code> (as described at the beginning of this section). The
filesystem might be accessed, but the source or expanded path
might be a non-existent path.</p>
<p>
</p>
<li><p><a name="node_idx_2508"></a><a name="node_kw_definitionsimplify-path"></a><code class=scheme>(simplify-path</code><tt> </tt><code class=scheme><span class=variable>path</span></code><tt> </tt>[<code class=scheme><span class=variable>use-filesystem?</span></code>]<code class=scheme>)</code> eliminates
up-directory (``..'') and same-directory (``.'') indicators in
<code class=scheme><span class=variable>path</span></code>, such that the result accesses the same file or directory
(if it exists) as <code class=scheme><span class=variable>path</span></code>; under Windows, if <code class=scheme><span class=variable>path</span></code> starts
<tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt>, no conversion is
performed. If no indicators are in <code class=scheme><span class=variable>path</span></code>, then <code class=scheme><span class=variable>path</span></code> is
returned. Otherwise, when <code class=scheme><span class=variable>use-filesystem?</span></code> is true (the
default), a complete path is returned; if <code class=scheme><span class=variable>path</span></code> is relative, it
is resolved with respect to the current directory, and up-directory
indicators are removed taking into account soft links (so that the
resulting path refers to the same directory as before). When
<code class=scheme><span class=variable>use-filesystem?</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then up-directory
indicators are removed by deleting a preceding path element, and the
result can be a relative path with up-directory indicators remaining
at the beginning of the path; similarly, the result can be the same
as <code class=scheme>(<code class=scheme>build-path</code> <span class=keyword>'</span><span class=variable>same</span>)</code> if eliminating up-directory
indicators leaves only same-directory indicators. For a complete
path, up-directory indicators are dropped when they refer to the
parent of a root directory. The filesystem might be accessed when
<code class=scheme><span class=variable>use-filesystem?</span></code> is true, but the source or expanded path
might be a non-existent path. If <code class=scheme><span class=variable>path</span></code> cannot be simplified due
to a cycle of links, the <a name="node_idx_2510"></a><code class=scheme>exn:fail:filesystem</code> exception is raised (but a
successfully simplified path may still involve a cycle of links if
the cycle did not inhibit the simplification).</p>
<p>
</p>
<li><p><a name="node_idx_2512"></a><a name="node_kw_definitionnormal-case-path"></a><code class=scheme>(normal-case-path</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> returns <code class=scheme><span class=variable>path</span></code> with
``normalized'' case letters. Under Unix and Mac OS X and Mac OS X, this
procedure always returns the input path, because filesystems for
these platforms can be case-sensitive. Under Windows, if the path
does not start <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt>, the
resulting string uses only lowercase letters, based on the current
locale. In addition, under Windows when the path does not start
<tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt>, all forward slashes
(``/'') are converted to backward slashes (``<tt>\</tt>''), and
trailing spaces and periods are removed. This procedure does not
access the filesystem.</p>
<p>
</p>
<li><p><a name="node_idx_2514"></a><a name="node_kw_definitionsplit-path"></a><code class=scheme>(split-path</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> deconstructs <code class=scheme><span class=variable>path</span></code> into a smaller
path and an immediate directory or file name. Three values are
returned (see section <a href="mzscheme-Z-H-2.html#node_sec_2.2">2.2</a>):
</p>
<ul><p>
</p>
<li><p><code class=scheme><span class=variable>base</span></code> is either
</p>
<ul>
<li><p>a path,
</p>
<li><p><code class=scheme><span class=selfeval>'relative</span></code><a name="node_idx_2516"></a> if <code class=scheme><span class=variable>path</span></code> is an immediate relative directory
or filename, or
</p>
<li><p><code class=scheme><span class=selfeval>#f</span></code> if <code class=scheme><span class=variable>path</span></code> is a root directory.
</p>
</ul><p></p>
<p>
</p>
<li><p><code class=scheme><span class=variable>name</span></code> is either
</p>
<ul>
<li><p>a directory-name path,
</p>
<li><p>a filename,
</p>
<li><p><code class=scheme><span class=selfeval>'up</span></code><a name="node_idx_2518"></a> if the last part of <code class=scheme><span class=variable>path</span></code> specifies the parent
directory of the preceding path (e.g., ``..'' under Unix), or
</p>
<li><p><code class=scheme><span class=selfeval>'same</span></code><a name="node_idx_2520"></a> if the last part of <code class=scheme><span class=variable>path</span></code> specifies the
same directory as the preceding path (e.g., ``.'' under Unix).
</p>
</ul><p></p>
<p>
</p>
<li><p><code class=scheme><span class=variable>must-be-dir?</span></code> is <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>path</span></code> explicitly
specifies a directory (e.g., with a trailing separator), <code class=scheme><span class=selfeval>#f</span></code>
otherwise. Note that <code class=scheme><span class=variable>must-be-dir?</span></code> does not specify whether
<code class=scheme><span class=variable>name</span></code> is actually a directory or not, but whether <code class=scheme><span class=variable>path</span></code>
syntactically specified a directory.</p>
<p>
</p>
</ul><p>
If <code class=scheme><span class=variable>base</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then <code class=scheme><span class=variable>name</span></code> cannot be <code class=scheme><span class=selfeval>'up</span></code><a name="node_idx_2522"></a> or
<code class=scheme><span class=selfeval>'same</span></code><a name="node_idx_2524"></a>. This procedure does not access the filesystem.</p>
<p>
Under Windows, splitting a path that does not start
with <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt> can produce parts
that start with <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt>. For
example, splitting <tt><strong>C:/x /aux/</strong></tt> produces
<tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt>C:<tt>\</tt>x <tt>\</tt></strong></tt>
and
<tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt>REL<tt>\</tt><tt>\</tt>aux</strong></tt>;
the <tt><strong><tt>\</tt><tt>\</tt>?<tt>\</tt></strong></tt> is needed in these
cases to preserve a trailing space after <tt><strong>x</strong></tt> and to avoid
referring to the AUX devide instead of an <tt><strong>aux</strong></tt> file.</p>
<p>
<a name="node_idx_2526"></a><a name="node_kw_definitionpath-replace-suffix"></a><code class=scheme>(path-replace-suffix</code><tt> </tt><code class=scheme><span class=variable>path string-or-bytes</span></code><code class=scheme>)</code> returns a path that is
the same as <code class=scheme><span class=variable>path</span></code>, except that the suffix is changed to
<code class=scheme><span class=variable>string-or-bytes</span></code>. If <code class=scheme><span class=variable>path</span></code> as no suffix, then
<code class=scheme><span class=variable>string-or-bytes</span></code> is added to the path. A suffix is defined as a
period followed by any number of non-period characters/bytes at the
end of the pathname. If <code class=scheme><span class=variable>path</span></code> represents a root, the
<a name="node_idx_2528"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.3.2"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.3.2">11.3.2 Locating Paths</a></h3>
<p></p>
<p>
The <code class=scheme>find-system-path</code> and <code class=scheme>find-executable-path</code>
procedures locate useful files and directories:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2530"></a><a name="node_kw_definitionfind-system-path"></a><code class=scheme>(find-system-path</code><tt> </tt><code class=scheme><span class=variable>kind-symbol</span></code><code class=scheme>)</code> <a name="node_idx_2532"></a> returns a
machine-specific path for a standard type of path specified by
<code class=scheme><span class=variable>kind-symbol</span></code>, which must be one of the following:
</p>
<ul><p>
</p>
<li><p><code class=scheme><span class=selfeval>'home-dir</span></code><a name="node_idx_2534"></a> -- the current user's home directory.</p>
<p>
Under Unix and Mac OS X, this directory is determined by expanding
the path <tt><strong>~</strong></tt>, which is expanded by first checking for a
<tt><strong>HOME</strong></tt><a name="node_idx_2536"></a> environment variable. If none is defined, the
<tt><strong>USER</strong></tt><a name="node_idx_2538"></a> and <tt><strong>LOGNAME</strong></tt><a name="node_idx_2540"></a> environment variables are
consulted (in that order) to find a user name, and then system files
are consulted to locate the user's home directory.</p>
<p>
Under Windows, the user's home directory is the user-specific profile
directory as determined by the Windows registry. If the registry
cannot provide a directory for some reason, the value of the
<tt><strong>USERPROFILE</strong></tt><a name="node_idx_2542"></a> environment variable is used instead, as long
as it refers to a directory that exists. If <tt><strong>USERPROFILE</strong></tt> also
fails, the directory is the one specified by the
<tt><strong>HOMEDRIVE</strong></tt><a name="node_idx_2544"></a> and <tt><strong>HOMEPATH</strong></tt><a name="node_idx_2546"></a> environment variables.
If those environment variables are not defined, or if the indicated
directory still does not exist, the directory containing the MzScheme
executable is used as the home directory.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'pref-dir</span></code><a name="node_idx_2548"></a> -- the standard directory for storing
the current user's preferences. Under Unix, the directory is
<tt><strong>.plt-scheme</strong></tt> in the user's home directory. Under Windows, it
is <tt><strong>PLT Scheme</strong></tt> in the user's application-data folder as
specified by the Windows registry; the application-data folder is
usually <tt><strong>Application Data</strong></tt> in the user's profile
directory. Under Mac OS X, it is <tt><strong>Library/Preferences</strong></tt> in the
user's home directory. This directory might not exist.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'pref-file</span></code><a name="node_idx_2550"></a> -- a file that contains a symbol-keyed
association list of preference values. The file's directory path
always matches the result returned for <code class=scheme><span class=selfeval>'pref-dir</span></code>. The file
name is <tt><strong>plt-prefs.ss</strong></tt> under Unix and Windows, and it is
<tt><strong>org.plt-scheme.prefs.ss</strong></tt> under Mac OS X. The file's
directory might not exist. See also <code class=scheme>get-preference</code> in
Chapter <a href="../mzlib/mzlib-Z-H-17.html#node_chap_17">17</a>
in <a href="../mzlib/mzlib.html"><i>PLT MzLib: Libraries Manual</i></a>.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'temp-dir</span></code><a name="node_idx_2552"></a> -- the standard directory for storing
temporary files. Under Unix and Mac OS X, this is the directory specified by
the <tt><strong>TMPDIR</strong></tt><a name="node_idx_2554"></a> environment variable, if it is defined.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'init-dir</span></code><a name="node_idx_2556"></a> -- the directory containing the
initialization file used by stand-alone MzScheme application. It is
the same as the current user's home directory.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'init-file</span></code><a name="node_idx_2558"></a> -- the file loaded at start-up
by the stand-alone MzScheme application. The directory part
of the path is the same path as returned for <code class=scheme><span class=selfeval>'init-dir</span></code>.
The file name is platform-specific:
</p>
<ul><p>
</p>
<li><p>Unix and Mac OS X: <tt><strong>.mzschemerc</strong></tt><a name="node_idx_2560"></a>
</p>
<li><p>Windows: <tt><strong>mzschemerc.ss</strong></tt><a name="node_idx_2562"></a></p>
<p>
</p>
</ul><p></p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'addon-dir</span></code><a name="node_idx_2564"></a> -- a directory for installing PLT
Scheme extensions. It's the same as <code class=scheme><span class=selfeval>'pref-dir</span></code>, except under
Mac OS X, where it's <tt><strong>Library/PLT Scheme</strong></tt> in the user's home
directory. This directory might not exist.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'doc-dir</span></code><a name="node_idx_2566"></a> -- the standard directory for storing
the current user's documents. It's the same as <code class=scheme><span class=selfeval>'home-dir</span></code>
under Unix and Mac OS X. Under Windows, it is the user's documents folder as
specified by the Windows registry; the documents folder is usually
<tt><strong>My Documents</strong></tt> in the user's home directory.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'desk-dir</span></code><a name="node_idx_2568"></a> -- the directory for the current user's
desktop. Under Unix, it's the same as <code class=scheme><span class=selfeval>'home-dir</span></code>. Under
Windows, it is the user's desktop folder as specified by the Windows
registry; the documents folder is usually <tt><strong>Desktop</strong></tt> in the
user's home directory. Under Mac OS X, it is the desktop
directory, which is specifically <tt><strong>~/Desktop</strong></tt> under Mac OS X.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'sys-dir</span></code><a name="node_idx_2570"></a> -- the directory containing the
operating system for Windows. Under Unix and Mac OS X, the
result is <code class=scheme><span class=selfeval>"/"</span></code>.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'exec-file</span></code><a name="node_idx_2572"></a> -- the path of the MzScheme executable
as provided by the operating system for the current
invocation.<a name="node_call_footnote_36"></a><a href="#node_footnote_36"><sup><small>36</small></sup></a></p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'run-file</span></code><a name="node_idx_2574"></a> -- the path of the current executable;
this may be different from result for <code class=scheme><span class=selfeval>'exec-file</span></code> because an
alternate path was provided through a <tt>--name</tt> or <tt>-N</tt>
command-line flag to stand-alone MzScheme (or MrEd), or because an
embedding executable installed an alternate path. In particular a
``launcher'' script created by <code class=scheme>make-mzscheme-launcher</code>
sets this path to the script's path. In the stand-alone MzScheme
application, this path is also bound initially to
<a name="node_idx_2576"></a><code class=scheme>program</code>.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'collects-dir</span></code><a name="node_idx_2578"></a> -- a path to the main collection
of libraries (see section <a href="mzscheme-Z-H-16.html#node_chap_16">16</a>). If this path is relative, it's
relative to the directory of <code class=scheme>(<code class=scheme>find-system-path</code> <span class=keyword>'</span><span class=variable>exec-file</span>)</code>.
This path is normally embedded in a stand-alone MzScheme executable,
but it can be overridden by the <tt>--collects</tt> or <tt>-X</tt>
command-line flag.</p>
<p>
</p>
<li><p><code class=scheme><span class=selfeval>'orig-dir</span></code><a name="node_idx_2580"></a> -- the current directory at start-up,
which can be useful in converting a relative-path result from
<code class=scheme>(<code class=scheme>find-system-path</code> <span class=keyword>'</span><span class=variable>exec-file</span>)</code>
or <code class=scheme>(<code class=scheme>find-system-path</code> <span class=keyword>'</span><span class=variable>run-file</span>)</code> to a complete path.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<li><p><a name="node_idx_2582"></a><a name="node_kw_definitionpath-list-string->path-list"></a><code class=scheme>(path-list-string->path-list</code><tt> </tt><code class=scheme><span class=variable>string default-path-list</span></code><code class=scheme>)</code>
parses a string or byte string containing a list of paths, and
returns a list of path strings. Under Unix and Mac OS X, paths in a path
list are separated by a colon (``:''); under Windows,
paths are separated by a semi-colon (``;''). Whenever the path list
contains an empty path, the list <code class=scheme><span class=variable>default-path-list</span></code> is spliced
into the returned list of paths. Parts of <code class=scheme><span class=variable>string</span></code> that do not
form a valid path are not included in the returned list.</p>
<p>
</p>
<li><p><a name="node_idx_2584"></a><a name="node_kw_definitionfind-executable-path"></a><code class=scheme>(find-executable-path</code><tt> </tt><code class=scheme><span class=variable>program-sub-path related-sub-path</span></code><code class=scheme>)</code>
finds a path for the executable <code class=scheme><span class=variable>program-sub-path</span></code>, returning
<code class=scheme><span class=selfeval>#f</span></code> if the path cannot be found.</p>
<p>
If <code class=scheme><span class=variable>related-sub-path</span></code> is not <code class=scheme><span class=selfeval>#f</span></code>, then it must be a
relative path string, and the path found for
<code class=scheme><span class=variable>program-sub-path</span></code> must be such that the file or directory
<code class=scheme><span class=variable>related-sub-path</span></code> exists in the same directory as the
executable. The result is then the full path for the found
<code class=scheme><span class=variable>related-sub-path</span></code>, instead of the path for the executable.</p>
<p>
This procedure is used by MzScheme (as a stand-alone executable) to
find the standard library collection directory (see Chapter <a href="mzscheme-Z-H-16.html#node_chap_16">16</a>).
In this case, <code class=scheme><span class=variable>program</span></code> is the name used to start MzScheme and
<code class=scheme><span class=variable>related</span></code> is <code class=scheme><span class=selfeval>"collects"</span></code>. The <code class=scheme><span class=variable>related-sub-path</span></code>
argument is used because, under Unix and Mac OS X, <code class=scheme><span class=variable>program-sub-path</span></code>
may involve to a sequence of soft links; in this case,
<code class=scheme><span class=variable>related-sub-path</span></code> determines which link in the chain is
relevant.</p>
<p>
If <code class=scheme><span class=variable>program-sub-path</span></code> has a directory path, exists as a file or
link to a file, and <code class=scheme><span class=variable>related-sub-path</span></code> is not <code class=scheme><span class=selfeval>#f</span></code>,
<code class=scheme><code class=scheme>find-executable-path</code></code> determines whether <code class=scheme><span class=variable>related-sub-path</span></code>
exists relative to the directory of <code class=scheme><span class=variable>program-sub-path</span></code>. If so,
the complete path for <code class=scheme><span class=variable>program-sub-path</span></code> is returned. Otherwise,
if <code class=scheme><span class=variable>program-sub-path</span></code> is a link to another file path, the
destination directory of the link is checked for
<code class=scheme><span class=variable>related-sub-path</span></code>. Further links are inspected until
<code class=scheme><span class=variable>related-sub-path</span></code> is found or the end of the chain of links is
reached.</p>
<p>
If <code class=scheme><span class=variable>program-sub-path</span></code> is a pathless name,
<code class=scheme><code class=scheme>find-executable-path</code></code> gets the value of the <tt><strong>PATH</strong></tt><a name="node_idx_2586"></a>
environment variable; if this environment variable is defined,
<code class=scheme><code class=scheme>find-executable-path</code></code> tries each path in <tt><strong>PATH</strong></tt> as a prefix
for <code class=scheme><span class=variable>program-sub-path</span></code> using the search algorithm described above
for path-containing <code class=scheme><span class=variable>program-sub-path</span></code>s. If the <tt><strong>PATH</strong></tt>
environment variable is not defined, <code class=scheme><span class=variable>program-sub-path</span></code> is
prefixed with the current directory and used in the search algorithm
above. (Under Windows, the current directory is always implicitly the
first item in <tt><strong>PATH</strong></tt>, so <code class=scheme><code class=scheme>find-executable-path</code></code> checks the
current directory first under Windows.)</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.3.3"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.3.3">11.3.3 Files</a></h3>
<p></p>
<p>
<a name="node_idx_2588"></a>
The file management utilities are:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2590"></a> <a name="node_idx_2592"></a><a name="node_kw_definitionfile-exists_Q_"></a><code class=scheme>(file-exists?</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code>
if a file (not a directory) <code class=scheme><span class=variable>path</span></code> exists, <code class=scheme><span class=selfeval>#f</span></code>
otherwise.<a name="node_call_footnote_37"></a><a href="#node_footnote_37"><sup><small>37</small></sup></a></p>
<p>
</p>
<li><p><a name="node_idx_2594"></a> <a name="node_idx_2596"></a><a name="node_kw_definitionlink-exists_Q_"></a><code class=scheme>(link-exists?</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code>
if a link <code class=scheme><span class=variable>path</span></code> exists (Unix and Mac OS X), <code class=scheme><span class=selfeval>#f</span></code>
otherwise. Note that the predicates <code class=scheme><code class=scheme>file-exists?</code></code> or
<code class=scheme><code class=scheme>directory-exists?</code></code> work on the final destination of a link or
series of links, while <code class=scheme><code class=scheme>link-exists?</code></code> only follows links to
resolve the base part of <code class=scheme><span class=variable>path</span></code> (i.e., everything except the last
name in the path). This procedure never raises the
<a name="node_idx_2598"></a><code class=scheme>exn:fail:filesystem</code> exception.</p>
<p>
</p>
<li><p><a name="node_idx_2600"></a> <a name="node_idx_2602"></a><a name="node_kw_definitiondelete-file"></a><code class=scheme>(delete-file</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> deletes the file
with path <code class=scheme><span class=variable>path</span></code> if it exists, returning void if a file
was deleted successfully, otherwise the
<a name="node_idx_2604"></a><code class=scheme>exn:fail:filesystem</code> exception is raised. If <code class=scheme><span class=variable>path</span></code> is a link, the link is
deleted rather than the destination of the link.</p>
<p>
</p>
<li><p><a name="node_idx_2606"></a> <a name="node_idx_2608"></a>
<a name="node_idx_2610"></a><a name="node_kw_definitionrename-file-or-directory"></a><code class=scheme>(rename-file-or-directory</code><tt> </tt><code class=scheme><span class=variable>old-path new-path</span></code><tt> </tt>[<code class=scheme><span class=variable>exists-ok?</span></code>]<code class=scheme>)</code> renames
the file or directory with path <code class=scheme><span class=variable>old-path</span></code> -- if it exists
-- to the path <code class=scheme><span class=variable>new-path</span></code>. If the file or directory is
renamed successfully, void is returned, otherwise the
<a name="node_idx_2612"></a><code class=scheme>exn:fail:filesystem</code> exception is raised.</p>
<p>
This procedure can be used to move a file/directory to a different
directory (on the same disk) as well as rename a file/directory
within a directory. Unless <code class=scheme><span class=variable>exists-ok?</span></code> is provided as a true
value, <code class=scheme><span class=variable>new-path</span></code> cannot refer to an existing file or
directory. Even if <code class=scheme><span class=variable>exists-ok?</span></code> is true, <code class=scheme><span class=variable>new-path</span></code> cannot
refer to an existing file when <code class=scheme><span class=variable>old-path</span></code> is a directory, and
vice versa. (If <code class=scheme><span class=variable>new-path</span></code> exists and is replaced, the
replacement is atomic in the filesystem, except under Windows 95, 98,
or Me. However, the check for existence is not included in the atomic
action, which means that race conditions are possible when
<code class=scheme><span class=variable>exists-ok?</span></code> is false or not supplied.)</p>
<p>
If <code class=scheme><span class=variable>old-path</span></code> is a link, the link is renamed rather than the
destination of the link, and it counts as a file for replacing any
existing <code class=scheme><span class=variable>new-path</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2614"></a>
<a name="node_idx_2616"></a><a name="node_kw_definitionfile-or-directory-modify-seconds"></a><code class=scheme>(file-or-directory-modify-seconds</code><tt> </tt><code class=scheme><span class=variable>path</span></code><tt> </tt>[<code class=scheme><span class=variable>secs-n fail-thunk</span></code>]<code class=scheme>)</code>
returns the file or directory's last modification date as
platform-specific seconds (see also section <a href="mzscheme-Z-H-15.html#node_sec_15.1">15.1</a>) when <code class=scheme><span class=variable>secs-n</span></code>
is not provided or is <code class=scheme><span class=selfeval>#f</span></code>.<a name="node_call_footnote_38"></a><a href="#node_footnote_38"><sup><small>38</small></sup></a> If <code class=scheme><span class=variable>secs-n</span></code> is provided and not
<code class=scheme><span class=selfeval>#f</span></code>, the access and modification times of <code class=scheme><span class=variable>path</span></code> are set
to the given time. On error (e.g., if no such file exists),
<code class=scheme><span class=variable>fail-thunk</span></code> is called if it is provided, otherwise the
<a name="node_idx_2618"></a><code class=scheme>exn:fail:filesystem</code> exception is raised</p>
<p>
</p>
<li><p><a name="node_idx_2620"></a> <a name="node_idx_2622"></a><a name="node_kw_definitionfile-or-directory-permissions"></a><code class=scheme>(file-or-directory-permissions</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code>
returns a list containing <code class=scheme><span class=selfeval>'read</span></code><a name="node_idx_2624"></a>, <code class=scheme><span class=selfeval>'write</span></code><a name="node_idx_2626"></a>,
and/or <code class=scheme><span class=selfeval>'execute</span></code><a name="node_idx_2628"></a> for the given file or directory path. On
error (e.g., if no such file exists),
the <a name="node_idx_2630"></a><code class=scheme>exn:fail:filesystem</code> exception is raised. Under Unix and Mac OS X, permissions are
checked for the current effective user instead of the real user.</p>
<p>
</p>
<li><p><a name="node_idx_2632"></a> <a name="node_idx_2634"></a><a name="node_kw_definitionfile-size"></a><code class=scheme>(file-size</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> returns the (logical)
size of the specified file in bytes. (Under Mac OS X, this size
excludes the resource-fork size.) On error (e.g., if no such file
exists), the <a name="node_idx_2636"></a><code class=scheme>exn:fail:filesystem</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2638"></a> <a name="node_idx_2640"></a><a name="node_kw_definitioncopy-file"></a><code class=scheme>(copy-file</code><tt> </tt><code class=scheme><span class=variable>src-path dest-path</span></code><code class=scheme>)</code>
creates the file <code class=scheme><span class=variable>dest-path</span></code> as a copy of <code class=scheme><span class=variable>src-path</span></code>. If the
file is successfully copied, void is returned, otherwise the
<a name="node_idx_2642"></a><code class=scheme>exn:fail:filesystem</code> exception is raised. If <code class=scheme><span class=variable>dest-path</span></code> already exists, the
copy will fail. File permissions are preserved in the copy. Under
Mac OS X, the resource fork is also preserved in the copy. If
<code class=scheme><span class=variable>src-path</span></code> refers to a link, the target of the link is copied,
rather than the link itself.</p>
<p>
</p>
<li><p><a name="node_idx_2644"></a> <a name="node_idx_2646"></a><a name="node_kw_definitionmake-file-or-directory-link"></a><code class=scheme>(make-file-or-directory-link</code><tt> </tt><code class=scheme><span class=variable>to-path path</span></code><code class=scheme>)</code>
creates a link <code class=scheme><span class=variable>path</span></code> to <code class=scheme><span class=variable>to-path</span></code> under Unix and Mac OS X. The
creation will fail if <code class=scheme><span class=variable>path</span></code> already exists. The <code class=scheme><span class=variable>to-path</span></code>
need not refer to an existing file or directory. If the link is created
successfully, void is returned, otherwise the
<a name="node_idx_2648"></a><code class=scheme>exn:fail:filesystem</code> exception is raised. Under Windows, the
<a name="node_idx_2650"></a><code class=scheme>exn:fail:unsupported</code> exception is raised always.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.3.4"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.3.4">11.3.4 Directories</a></h3>
<p></p>
<p>
<a name="node_idx_2652"></a>
The directory management utilities are:
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2654"></a>
<code class=scheme>(<a name="node_idx_2656"></a><code class=scheme>current-directory</code>)</code> returns the current directory
and <code class=scheme>(current-directory <code class=scheme><span class=variable>path</span></code>)</code> sets the current directory
to <code class=scheme><span class=variable>path</span></code>. This procedure is actually a parameter, as described
in section <a href="mzscheme-Z-H-7.html#node_sec_7.9.1.1">7.9.1.1</a>.</p>
<p>
</p>
<li><p><a name="node_idx_2658"></a><a name="node_kw_definitioncurrent-drive"></a><code class=scheme>(current-drive</code><code class=scheme>)</code> returns the current drive name under
Windows. For other platforms, the
<a name="node_idx_2660"></a><code class=scheme>exn:fail:unsupported</code> exception is raised. The current drive is always the
drive of the current directory.</p>
<p>
</p>
<li><p><a name="node_idx_2662"></a> <a name="node_idx_2664"></a><a name="node_kw_definitiondirectory-exists_Q_"></a><code class=scheme>(directory-exists?</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code>
returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>path</span></code> refers to a directory, <code class=scheme><span class=selfeval>#f</span></code>
otherwise.</p>
<p>
</p>
<li><p><a name="node_idx_2666"></a> <a name="node_idx_2668"></a><a name="node_kw_definitionmake-directory"></a><code class=scheme>(make-directory</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code> creates
a new directory with the path <code class=scheme><span class=variable>path</span></code>. If the directory is
created successfully, void is returned, otherwise the
<a name="node_idx_2670"></a><code class=scheme>exn:fail:filesystem</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2672"></a> <a name="node_idx_2674"></a><a name="node_kw_definitiondelete-directory"></a><code class=scheme>(delete-directory</code><tt> </tt><code class=scheme><span class=variable>path</span></code><code class=scheme>)</code>
deletes an existing directory with the path <code class=scheme><span class=variable>path</span></code>. If the
directory is deleted successfully, void is returned, otherwise
the <a name="node_idx_2676"></a><code class=scheme>exn:fail:filesystem</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2678"></a> <a name="node_idx_2680"></a>
<code class=scheme>(<a name="node_idx_2682"></a><code class=scheme>rename-file-or-directory</code> <code class=scheme><span class=variable>old-path</span></code> <code class=scheme><span class=variable>new-path</span></code> <code class=scheme><span class=variable>exists-ok?</span></code>)</code>, as
described in the previous section, renames directories.</p>
<p>
</p>
<li><p><a name="node_idx_2684"></a>
<code class=scheme>(<a name="node_idx_2686"></a><code class=scheme>file-or-directory-modify-seconds</code> <code class=scheme><span class=variable>path</span></code>)</code>, as
described in the previous section, gets directory dates.</p>
<p>
</p>
<li><p><a name="node_idx_2688"></a>
<code class=scheme>(<a name="node_idx_2690"></a><code class=scheme>file-or-directory-permissions</code> <code class=scheme><span class=variable>path</span></code>)</code>, as
described in the previous section, gets directory permissions.</p>
<p>
</p>
<li><p><a name="node_idx_2692"></a> <a name="node_idx_2694"></a><a name="node_kw_definitiondirectory-list"></a><code class=scheme>(directory-list</code><tt> </tt>[<code class=scheme><span class=variable>path</span></code>]<code class=scheme>)</code>
returns a list of all files and directories in the directory
specified by <code class=scheme><span class=variable>path</span></code>. If <code class=scheme><span class=variable>path</span></code> is omitted, a list of files
and directories in the current directory is returned.</p>
<p>
</p>
<li><p><a name="node_idx_2696"></a> <a name="node_idx_2698"></a><a name="node_kw_definitionfilesystem-root-list"></a><code class=scheme>(filesystem-root-list</code><code class=scheme>)</code> returns a
list of all current root directories. Obtaining this list can be
particularly slow under Windows.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.4"></a>
<h2><a href="mzscheme.html#node_toc_node_sec_11.4">11.4 Networking</a></h2>
<p><a name="node_idx_2700"></a></p>
<p>
<a name="node_idx_2702"></a> <a name="node_idx_2704"></a> <a name="node_idx_2706"></a>
MzScheme supports networking with the TCP and UDP protocols.</p>
<p>
</p>
<a name="node_sec_11.4.1"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.4.1">11.4.1 TCP</a></h3>
<p></p>
<p>
<a name="node_idx_2708"></a>
For information about TCP in general, see <i>TCP/IP Illustrated,
Volume 1</i> by W. Richard Stevens.</p>
<p>
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2710"></a><a name="node_kw_definitiontcp-listen"></a><code class=scheme>(tcp-listen</code><tt> </tt><code class=scheme><span class=variable>port-k</span></code><tt> </tt>[<code class=scheme><span class=variable>max-allow-wait-k reuse? hostname-string-or-false</span></code>]<code class=scheme>)</code>
creates a ``listening'' server on the local machine at the specified
port number (where <code class=scheme><span class=variable>port-k</span></code> is an exact integer between
<code class=scheme><span class=selfeval>1</span></code> and <code class=scheme><span class=selfeval>65535</span></code> inclusive). The <code class=scheme><span class=variable>max-allow-wait-k</span></code>
argument determines the maximum number of client connections that can
be waiting for acceptance. (When <code class=scheme><span class=variable>max-allow-wait-k</span></code> clients are
waiting acceptance, no new client connections can be made.) The
default value for <code class=scheme><span class=variable>max-allow-wait-k</span></code> argument is <code class=scheme><span class=selfeval>4</span></code>.</p>
<p>
If the <code class=scheme><span class=variable>reuse?</span></code> argument is true, then <code class=scheme><code class=scheme>tcp-listen</code></code> will
create a listener even if the port is involved in a <tt>TIME_WAIT</tt>
state. Such a use of <code class=scheme><span class=variable>reuse?</span></code> defeats certain guarantees of the
TCP protocol; see Stevens's book for details. Furthermore, on many
modern platforms, a true value for <code class=scheme><span class=variable>reuse?</span></code> overrides <tt>TIME_WAIT</tt> only if the listener was previously created with a true
value for <code class=scheme><span class=variable>reuse?</span></code>. The default for <code class=scheme><span class=variable>reuse?</span></code> is
<code class=scheme><span class=selfeval>#f</span></code>.</p>
<p>
If <code class=scheme><span class=variable>hostname-string-or-false</span></code> is <code class=scheme><span class=selfeval>#f</span></code> (the default), then
the listener accepts connections to all of the listening machine's
addresses.<a name="node_call_footnote_39"></a><a href="#node_footnote_39"><sup><small>39</small></sup></a> Otherwise, the listener accepts connections
only at the interface(s) associated with the given hostname. For
example, providing <code class=scheme><span class=selfeval>"127.0.0.1"</span></code>
as <code class=scheme><span class=variable>hostname-string-or-false</span></code> creates a listener that accepts
only connections to <code class=scheme><span class=selfeval>"127.0.0.1"</span></code> (the loopback interface) from
the local machine.</p>
<p>
The return value of <code class=scheme><code class=scheme>tcp-listen</code></code> is a TCP listener value. This
value can be used in future calls to <code class=scheme><code class=scheme>tcp-accept</code></code>,
<code class=scheme><code class=scheme>tcp-accept-ready?</code></code>, and <code class=scheme><code class=scheme>tcp-close</code></code>. Each new TCP listener
value is placed into the management of the current custodian (see
section <a href="mzscheme-Z-H-9.html#node_sec_9.2">9.2</a>).</p>
<p>
If the server cannot be started by <code class=scheme><code class=scheme>tcp-listen</code></code>, the
<a name="node_idx_2712"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2714"></a><a name="node_kw_definitiontcp-connect"></a><code class=scheme>(tcp-connect</code><tt> </tt><code class=scheme><span class=variable>hostname-string
port-k</span></code><tt> </tt>[<code class=scheme><span class=variable>local-hostname-string-or-false local-port-k-or-false</span></code>]<code class=scheme>)</code>
attempts to connect as a client to a listening server.
The <code class=scheme><span class=variable>hostname-string</span></code> argument is the server host's Internet
address name<a name="node_call_footnote_40"></a><a href="#node_footnote_40"><sup><small>40</small></sup></a> (e.g., <code class=scheme><span class=selfeval>"www.plt-scheme.org"</span></code>), and <code class=scheme><span class=variable>port-k</span></code> (an
exact integer between <code class=scheme><span class=selfeval>1</span></code> and <code class=scheme><span class=selfeval>65535</span></code>) is the port
where the server is listening.</p>
<p>
The optional <code class=scheme><span class=variable>local-hostname-string-or-false</span></code>
and <code class=scheme><span class=variable>local-port-k-or-false</span></code> specify the client's address and
port. If both are <code class=scheme><span class=selfeval>#f</span></code> (the default), the client's address and
port are selected
automatically. If <code class=scheme><span class=variable>local-hostname-string-or-false</span></code> is
not <code class=scheme><span class=selfeval>#f</span></code>, then <code class=scheme><span class=variable>local-port-k-or-false</span></code> must be
non-<code class=scheme><span class=selfeval>#f</span></code>. If <code class=scheme><span class=variable>local-port-k-or-false</span></code> is non-<code class=scheme><span class=selfeval>#f</span></code>
and <code class=scheme><span class=variable>local-hostname-string-or-false</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then the
given port is used but the address is selected automatically.</p>
<p>
Two values (see section <a href="mzscheme-Z-H-2.html#node_sec_2.2">2.2</a>) are returned by <code class=scheme><code class=scheme>tcp-connect</code></code>: an
input port and an output port. Data can be received from the server
through the input port and sent to the server through the output
port. If the server is a MzScheme process, it can obtain ports to
communicate to the client with <code class=scheme><code class=scheme>tcp-accept</code></code>. These ports are
placed into the management of the current custodian (see
section <a href="mzscheme-Z-H-9.html#node_sec_9.2">9.2</a>); if a custodian shuts down the connection, it
must abort the connection.</p>
<p>
Initially, the returned input port is block-buffered, and the
returned output port is block-buffered. Change the buffer mode using
<code class=scheme>file-stream-buffer-mode</code> (see section <a href="#node_sec_11.1.6">11.1.6</a>).</p>
<p>
Both of the returned ports must be closed to terminate the
TCP connection. When both ports are still open, closing the output port
with <code class=scheme>close-output-port</code> sends a TCP close to the server
(which is seen as an end-of-file if the server reads the connection
through a port). In contrast, <code class=scheme>tcp-abandon-port</code> (see below)
closes the output port, but does not send a TCP close until the input
port is also closed.</p>
<p>
If a connection cannot be established by <code class=scheme><code class=scheme>tcp-connect</code></code>, the
<a name="node_idx_2716"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2718"></a><a name="node_kw_definitiontcp-connect/enable-break"></a><code class=scheme>(tcp-connect/enable-break</code><tt> </tt><code class=scheme><span class=variable>hostname-string
port-k</span></code><tt> </tt>[<code class=scheme><span class=variable>local-hostname-string local-port-k</span></code>]<code class=scheme>)</code> is
like <code class=scheme><code class=scheme>tcp-connect</code></code>, but breaking is enabled
(see section <a href="mzscheme-Z-H-6.html#node_sec_6.6">6.6</a>) while trying to connect. If breaking is
disabled when <code class=scheme><code class=scheme>tcp-connect/enable-break</code></code> is called, then
either ports are returned or the <a name="node_idx_2720"></a><code class=scheme>exn:break</code> exception is raised,
but not both.</p>
<p>
</p>
<li><p><a name="node_idx_2722"></a><a name="node_kw_definitiontcp-accept"></a><code class=scheme>(tcp-accept</code><tt> </tt><code class=scheme><span class=variable>tcp-listener</span></code><code class=scheme>)</code> accepts a client connection for
the server associated with <code class=scheme><span class=variable>tcp-listener</span></code>. The <code class=scheme><span class=variable>tcp-listener</span></code>
argument is a TCP listener value returned by <code class=scheme><code class=scheme>tcp-listen</code></code>. If no
client connection is waiting on the listening port, the call to
<code class=scheme><code class=scheme>tcp-accept</code></code> will block. (See also <code class=scheme><code class=scheme>tcp-accept-ready?</code></code>,
below.)</p>
<p>
Two values (see section <a href="mzscheme-Z-H-2.html#node_sec_2.2">2.2</a>) are returned by <code class=scheme><code class=scheme>tcp-accept</code></code>: an
input port and an output port. Data can be received from the client
through the input port and sent to the client through the output
port. These ports are placed into the management of the current
custodian (see section <a href="mzscheme-Z-H-9.html#node_sec_9.2">9.2</a>).</p>
<p>
Initially, the returned input port is block-buffered, and the
returned output port is block-buffered. Change the buffer mode using
<code class=scheme>file-stream-buffer-mode</code> (see section <a href="#node_sec_11.1.6">11.1.6</a>).</p>
<p>
Both of the returned ports must be closed to terminate the
connection. When both ports are still open, closing the output port
with <code class=scheme>close-output-port</code> sends a TCP close to the client
(which is seen as an end-of-file if the client reads the connection
through a port). In contrast, <code class=scheme>tcp-abandon-port</code> (see below)
closes the output port, but does not send a TCP close until the input
port is also closed.</p>
<p>
If a connection cannot be accepted by <code class=scheme><code class=scheme>tcp-accept</code></code>, or if the
listener has been closed, the <a name="node_idx_2724"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2726"></a><a name="node_kw_definitiontcp-accept-ready_Q_"></a><code class=scheme>(tcp-accept-ready?</code><tt> </tt><code class=scheme><span class=variable>tcp-listener</span></code><code class=scheme>)</code> tests whether an
unaccepted client has connected to the server associated with
<code class=scheme><span class=variable>tcp-listener</span></code>. The <code class=scheme><span class=variable>tcp-listener</span></code> argument is a TCP listener
value returned by <code class=scheme><code class=scheme>tcp-listen</code></code>. If a client is waiting, the
return value is <code class=scheme><span class=selfeval>#t</span></code>, otherwise it is <code class=scheme><span class=selfeval>#f</span></code>. A client is
accepted with the <code class=scheme><code class=scheme>tcp-accept</code></code> procedure, which returns ports for
communicating with the client and removes the client from the list of
unaccepted clients.</p>
<p>
If the listener has been closed, the <a name="node_idx_2728"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2730"></a><a name="node_kw_definitiontcp-accept/enable-break"></a><code class=scheme>(tcp-accept/enable-break</code><tt> </tt><code class=scheme><span class=variable>tcp-listener</span></code><code class=scheme>)</code> is like
<code class=scheme><code class=scheme>tcp-accept</code></code>, but breaking is enabled (see
section <a href="mzscheme-Z-H-6.html#node_sec_6.6">6.6</a>) while trying to accept a connection. If
breaking is disabled when <code class=scheme><code class=scheme>tcp-accept/enable-break</code></code> is called,
then either ports are returned or the <a name="node_idx_2732"></a><code class=scheme>exn:break</code> exception is
raised, but not both.</p>
<p>
</p>
<li><p><a name="node_idx_2734"></a><a name="node_kw_definitiontcp-close"></a><code class=scheme>(tcp-close</code><tt> </tt><code class=scheme><span class=variable>tcp-listener</span></code><code class=scheme>)</code> shuts down the server associated
with <code class=scheme><span class=variable>tcp-listener</span></code>. The <code class=scheme><span class=variable>tcp-listener</span></code> argument is a TCP
listener value returned by <code class=scheme><code class=scheme>tcp-listen</code></code>. All unaccepted clients
receive an end-of-file from the server; connections to accepted
clients are unaffected.</p>
<p>
If the listener has already been closed, the <a name="node_idx_2736"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
The listener's port number may not become immediately available for
new listeners (with the default <code class=scheme><span class=variable>reuse?</span></code> argument of
<code class=scheme><code class=scheme>tcp-listen</code></code>). For further information, see Stevens's
explanation of the <tt>TIME_WAIT</tt> TCP state.</p>
<p>
</p>
<li><p><a name="node_idx_2738"></a><a name="node_kw_definitiontcp-listener_Q_"></a><code class=scheme>(tcp-listener?</code><tt> </tt><code class=scheme><span class=variable>v</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>v</span></code> is a TCP
listener value created by <code class=scheme><code class=scheme>tcp-listen</code></code>, <code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
</p>
<li><p><a name="node_idx_2740"></a><a name="node_kw_definitiontcp-accept-evt"></a><code class=scheme>(tcp-accept-evt</code><tt> </tt><code class=scheme><span class=variable>tcp-listener</span></code><code class=scheme>)</code> returns a synchronizable
event (see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>) that is in a blocking state when
<code class=scheme>tcp-accept</code> on <code class=scheme><span class=variable>tcp-listener</span></code> would block. If the event
is chosen in a synchronization, the result is a list of two items,
which correspond to the two results of <code class=scheme>tcp-accept</code>. (If the
event is not chosen, no connections are accepted.)</p>
<p>
</p>
<li><p><a name="node_idx_2742"></a><a name="node_kw_definitiontcp-abandon-port"></a><code class=scheme>(tcp-abandon-port</code><tt> </tt><code class=scheme><span class=variable>tcp-port</span></code><code class=scheme>)</code> is like
<code class=scheme>close-output-port</code> or <code class=scheme>close-input-port</code> (depending on
whether <code class=scheme><span class=variable>tcp-port</span></code> is an input or output port), but if
<code class=scheme><span class=variable>tcp-port</span></code> is an output port and its associated input port is not
yet closed, then the other end of the TCP connection does not
receive a TCP close message until the input port is also
closed.<a name="node_call_footnote_41"></a><a href="#node_footnote_41"><sup><small>41</small></sup></a></p>
<p>
</p>
<li><p><a name="node_idx_2744"></a><a name="node_kw_definitiontcp-addresses"></a><code class=scheme>(tcp-addresses</code><tt> </tt><code class=scheme><span class=variable>tcp-port</span></code><code class=scheme>)</code> returns two strings. The first
string is the Internet address for the local machine a viewed by the
given TCP port's connection.<a name="node_call_footnote_42"></a><a href="#node_footnote_42"><sup><small>42</small></sup></a> The second string is the Internet address for
the other end of the connection.</p>
<p>
If the given port has been closed, the <a name="node_idx_2746"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2748"></a><a name="node_kw_definitiontcp-port_Q_"></a><code class=scheme>(tcp-port?</code><tt> </tt><code class=scheme><span class=variable>v</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>v</span></code> is a port
returned by <code class=scheme>tcp-accept</code>, <code class=scheme>tcp-connect</code>,
<code class=scheme>tcp-accept/enable-break</code>, or
<code class=scheme>tcp-connect/enable-break</code>, <code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<a name="node_sec_11.4.2"></a>
<h3><a href="mzscheme.html#node_toc_node_sec_11.4.2">11.4.2 UDP</a></h3>
<p></p>
<p>
<a name="node_idx_2750"></a>
For information about UDP in general, see <i>TCP/IP Illustrated,
Volume 1</i> by W. Richard Stevens (which discusses UDP in addition to
TCP).</p>
<p>
</p>
<ul><p>
</p>
<li><p><a name="node_idx_2752"></a><a name="node_kw_definitionudp-open-socket"></a><code class=scheme>(udp-open-socket</code><tt> </tt>[<code class=scheme><span class=variable>family-hostname-string-or-false
family-port-k-or-false</span></code>]<code class=scheme>)</code> creates and returns a UDP socket to send and
receive datagrams (broadcasting is allowed). Initially, the socket is
not bound or connected to any address or port.</p>
<p>
If <code class=scheme><span class=variable>family-hostname-string-or-false</span></code>
or <code class=scheme><span class=variable>family-port-k-or-false</span></code> is provided and not <code class=scheme><span class=selfeval>#f</span></code>, then
the socket's protocol family is determined from these arguments. The
socket is <em>not</em> bound to the hostname or port number. For
example, the arguments might be the hostname and port to which
messages will be sent through the socket, which ensures that the
socket's protocol family is consistent with the
destination. Alternately, the arguments might be the same as for a
future call to <code class=scheme>udp-bind!</code>, which ensures that the socket's
protocol family is consistent with the binding. If
neither <code class=scheme><span class=variable>family-hostname-string-or-false</span></code>
nor <code class=scheme><span class=variable>family-port-k-or-false</span></code> is provided as non-<code class=scheme><span class=selfeval>#f</span></code>, then
the socket's protocol family is IPv4.</p>
<p>
</p>
<li><p><a name="node_idx_2754"></a><a name="node_kw_definitionudp-bind!"></a><code class=scheme>(udp-bind!</code><tt> </tt><code class=scheme><span class=variable>udp-socket hostname-string-or-false port-k</span></code><code class=scheme>)</code>
binds an unbound <code class=scheme><span class=variable>udp-socket</span></code> to the local port number
<code class=scheme><span class=variable>port-k</span></code> (an exact integer between <code class=scheme><span class=selfeval>1</span></code> and
<code class=scheme><span class=selfeval>65535</span></code>). The result is always void.</p>
<p>
If <code class=scheme><span class=variable>hostname-string-or-false</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then the socket
accepts connections to all of the listening machine's IP addresses at
<code class=scheme><span class=variable>port-k</span></code>. Otherwise, the socket accepts connections only at the
IP address associated with the given name. For example, providing
<code class=scheme><span class=selfeval>"127.0.0.1"</span></code> as <code class=scheme><span class=variable>hostname-string-or-false</span></code> typically
creates a listener that accepts only connections to
<code class=scheme><span class=selfeval>"127.0.0.1"</span></code> from the local machine.</p>
<p>
A socket cannot receive datagrams until it is bound to a local
address and port. If a socket is not bound before it is used with a
sending procedure <code class=scheme>udp-send</code>, <code class=scheme>udp-send-to</code>, etc., the
sending procedure binds the socket to a random local port. Similarly,
if an event from <code class=scheme>udp-send-evt</code> or <code class=scheme>udp-send-to-evt</code> is
chosen for a synchronization (see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>), the socket is
bound; if the event is not chosen, the socket may or may not become
bound. The binding of a bound socket cannot be changed.</p>
<p>
If <code class=scheme><span class=variable>udp-socket</span></code> is already bound or closed, the
<a name="node_idx_2756"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2758"></a><a name="node_kw_definitionudp-connect!"></a><code class=scheme>(udp-connect!</code><tt> </tt><code class=scheme><span class=variable>udp-socket hostname-string-or-false
port-k-or-false</span></code><code class=scheme>)</code> connects the socket to the indicated remote address
and port if <code class=scheme><span class=variable>hostname-string-or-false</span></code> is a string and
<code class=scheme><span class=variable>port-k-or-false</span></code> is an exact integer between <code class=scheme><span class=selfeval>1</span></code> and
<code class=scheme><span class=selfeval>65535</span></code>. The result is always void.</p>
<p>
If <code class=scheme><span class=variable>hostname-string-or-false</span></code> is <code class=scheme><span class=selfeval>#f</span></code>, then
<code class=scheme><span class=variable>port-k-or-false</span></code> also must be <code class=scheme><span class=selfeval>#f</span></code>, and the port is
disconnected (if connected). If one of <code class=scheme><span class=variable>hostname-string-or-false</span></code>
or <code class=scheme><span class=variable>port-k-or-false</span></code> is <code class=scheme><span class=selfeval>#f</span></code> and the other is not, the
<a name="node_idx_2760"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
A connected socket can be used with <code class=scheme>udp-send</code> (not
<code class=scheme>udp-send-to</code>), and it accepts datagrams only from the
connected address and port. A socket need not be connected to receive
datagrams. A socket can be connected, re-connected, and disconnected
any number of times.</p>
<p>
If <code class=scheme><span class=variable>udp-socket</span></code> is closed, the <a name="node_idx_2762"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2764"></a><a name="node_kw_definitionudp-send-to"></a><code class=scheme>(udp-send-to</code><tt> </tt><code class=scheme><span class=variable>udp-socket hostname-address port-k
bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> sends <code class=scheme>(subbytes <code class=scheme><span class=variable>bytes</span></code>
<code class=scheme><span class=variable>start-k</span></code> <code class=scheme><span class=variable>end-k</span></code>)</code> as a datagram from the unconnected
<code class=scheme><span class=variable>udp-socket</span></code> to the socket at the remote machine
<code class=scheme><span class=variable>hostname-address</span></code> on the port <code class=scheme><span class=variable>port-k</span></code>. The <code class=scheme><span class=variable>udp-socket</span></code>
need not be bound or connected; if it is not bound,
<code class=scheme>udp-send-to</code> binds it to a random local port. If the socket's
outgoing datagram queue is too full to support the send,
<code class=scheme>udp-send-to</code> blocks until the datagram can be queued. The
result is always void.</p>
<p>
The optional <code class=scheme><span class=variable>start-k</span></code> argument defaults to <code class=scheme><span class=selfeval>0</span></code>, and the
optional <code class=scheme><span class=variable>end-k</span></code> argument defaults to the length of <code class=scheme><span class=variable>bytes</span></code>.
If <code class=scheme><span class=variable>start-k</span></code> is greater than the length of <code class=scheme><span class=variable>bytes</span></code>, or if
<code class=scheme><span class=variable>end-k</span></code> is less than <code class=scheme><span class=variable>start-k</span></code> or greater than the length of
<code class=scheme><span class=variable>bytes</span></code>, the <a name="node_idx_2766"></a><code class=scheme>exn:fail:contract</code> exception is raised.</p>
<p>
If <code class=scheme><span class=variable>udp-socket</span></code> is closed or connected, the
<a name="node_idx_2768"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2770"></a><a name="node_kw_definitionudp-send"></a><code class=scheme>(udp-send</code><tt> </tt><code class=scheme><span class=variable>udp-socket bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> is like
<code class=scheme>udp-send-to</code>, except that <code class=scheme><span class=variable>udp-socket</span></code> must be connected,
and the datagram goes to the connection target. If <code class=scheme><span class=variable>udp-socket</span></code>
is closed or unconnected, the <a name="node_idx_2772"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2774"></a><a name="node_kw_definitionudp-send-to*"></a><code class=scheme>(udp-send-to*</code><tt> </tt><code class=scheme><span class=variable>udp-socket hostname-address port-k
bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> is like <code class=scheme>udp-send-to</code>, except that it
never blocks; if the socket's outgoing queue is too full to support
the send, <code class=scheme><span class=selfeval>#f</span></code> is returned, otherwise the datagram is queued
and the result is <code class=scheme><span class=selfeval>#t</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2776"></a><a name="node_kw_definitionudp-send*"></a><code class=scheme>(udp-send*</code><tt> </tt><code class=scheme><span class=variable>udp-socket bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> is like
<code class=scheme>udp-send</code>, except that (like <code class=scheme>udp-send-to</code>) it
never blocks and returns <code class=scheme><span class=selfeval>#f</span></code> or <code class=scheme><span class=selfeval>#t</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2778"></a><a name="node_kw_definitionudp-send-to/enable-break"></a><code class=scheme>(udp-send-to/enable-break</code><tt> </tt><code class=scheme><span class=variable>udp-socket hostname-address
port-k bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> is like <code class=scheme>udp-send-to</code>, but
breaking is enabled (see section <a href="mzscheme-Z-H-6.html#node_sec_6.6">6.6</a>) while trying to send
the datagram. If breaking is disabled when
<code class=scheme>udp-send-to/enable-break</code> is called, then either the datagram
is sent or the <a name="node_idx_2780"></a><code class=scheme>exn:break</code> exception is raised, but not both.</p>
<p>
</p>
<li><p><a name="node_idx_2782"></a><a name="node_kw_definitionudp-send/enable-break"></a><code class=scheme>(udp-send/enable-break</code><tt> </tt><code class=scheme><span class=variable>udp-socket bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code>
is like <code class=scheme>udp-send</code>, except that breaks are enabled like
<code class=scheme>udp-send-to/enable-break</code>.</p>
<p>
</p>
<li><p><a name="node_idx_2784"></a><a name="node_kw_definitionudp-receive!"></a><code class=scheme>(udp-receive!</code><tt> </tt><code class=scheme><span class=variable>udp-socket mutable-bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code>
accepts up to <code class=scheme><span class=variable>end-k</span></code> <tt>-</tt> <code class=scheme><span class=variable>start-k</span></code> bytes of
<code class=scheme><span class=variable>udp-socket</span></code>'s next incoming datagram into <code class=scheme><span class=variable>mutable-bytes</span></code>,
writing the datagram bytes starting at position <code class=scheme><span class=variable>start-k</span></code>
within <code class=scheme><span class=variable>mutable-bytes</span></code>. The <code class=scheme><span class=variable>udp-socket</span></code> must be bound to a
local address and port (but need not be connected). If no incoming
datagram is immediately available, <code class=scheme>udp-receive!</code> blocks
until one is available.</p>
<p>
Three values are returned: an exact integer that indicates the number
of received bytes (between <code class=scheme><span class=selfeval>0</span></code> and
<code class=scheme><span class=variable>end-k</span></code> <tt>-</tt> <code class=scheme><span class=variable>start-k</span></code>), a hostname string
indicating the source address of the datagram, and an exact integer
between <code class=scheme><span class=selfeval>1</span></code> and <code class=scheme><span class=selfeval>65535</span></code> indicating the source port of
the datagram. If the received datagram is longer than
<code class=scheme><span class=variable>end-k</span></code> <tt>-</tt> <code class=scheme><span class=variable>start-k</span></code> bytes, the remainder is
discarded.</p>
<p>
The optional <code class=scheme><span class=variable>start-k</span></code> argument defaults to <code class=scheme><span class=selfeval>0</span></code>, and the
optional <code class=scheme><span class=variable>end-k</span></code> argument defaults to the length of
<code class=scheme><span class=variable>mutable-bytes</span></code>. If <code class=scheme><span class=variable>start-k</span></code> is greater than the length of
<code class=scheme><span class=variable>mutable-bytes</span></code>, or if <code class=scheme><span class=variable>end-k</span></code> is less than <code class=scheme><span class=variable>start-k</span></code> or
greater than the length of <code class=scheme><span class=variable>mutable-bytes</span></code>, the
<a name="node_idx_2786"></a><code class=scheme>exn:fail:contract</code> exception is raised. </p>
<p>
</p>
<li><p><a name="node_idx_2788"></a><a name="node_kw_definitionudp-receive!*"></a><code class=scheme>(udp-receive!*</code><tt> </tt><code class=scheme><span class=variable>udp-socket mutable-bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k
end-k</span></code>]<code class=scheme>)</code> is like <code class=scheme>udp-receive!</code>, except that it never blocks. If
no datagram is available, the three result values are all
<code class=scheme><span class=selfeval>#f</span></code>.</p>
<p>
</p>
<li><p><a name="node_idx_2790"></a><a name="node_kw_definitionudp-receive!/enable-break"></a><code class=scheme>(udp-receive!/enable-break</code><tt> </tt><code class=scheme><span class=variable>udp-socket
mutable-bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> is like <code class=scheme>udp-receive!</code>, but
breaking is enabled (see section <a href="mzscheme-Z-H-6.html#node_sec_6.6">6.6</a>) while trying to
receive the datagram. If breaking is disabled when
<code class=scheme>udp-receive!/enable-break</code> is called, then either a datagram
is received or the <a name="node_idx_2792"></a><code class=scheme>exn:break</code> exception is raised, but not
both.</p>
<p>
</p>
<li><p><a name="node_idx_2794"></a><a name="node_kw_definitionudp-close"></a><code class=scheme>(udp-close</code><tt> </tt><code class=scheme><span class=variable>udp-socket</span></code><code class=scheme>)</code> closes <code class=scheme><span class=variable>udp-socket</span></code>, discarding
unreceived datagrams. If the socket is already closed, the
<a name="node_idx_2796"></a><code class=scheme>exn:fail:network</code> exception is raised.</p>
<p>
</p>
<li><p><a name="node_idx_2798"></a><a name="node_kw_definitionudp_Q_"></a><code class=scheme>(udp?</code><tt> </tt><code class=scheme><span class=variable>v</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if <code class=scheme><span class=variable>v</span></code> is a socket created
by <code class=scheme>udp-open-socket</code>, <code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
</p>
<li><p><a name="node_idx_2800"></a><a name="node_kw_definitionudp-bound_Q_"></a><code class=scheme>(udp-bound?</code><tt> </tt><code class=scheme><span class=variable>udp-socket</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if
<code class=scheme><span class=variable>udp-socket</span></code> is bound to a local address and port, <code class=scheme><span class=selfeval>#f</span></code>
otherwise.</p>
<p>
</p>
<li><p><a name="node_idx_2802"></a><a name="node_kw_definitionudp-connected_Q_"></a><code class=scheme>(udp-connected?</code><tt> </tt><code class=scheme><span class=variable>udp-socket</span></code><code class=scheme>)</code> returns <code class=scheme><span class=selfeval>#t</span></code> if
<code class=scheme><span class=variable>udp-socket</span></code> is connected to a remote address and port,
<code class=scheme><span class=selfeval>#f</span></code> otherwise.</p>
<p>
</p>
<li><p><a name="node_idx_2804"></a><a name="node_kw_definitionudp-send-ready-evt"></a><code class=scheme>(udp-send-ready-evt</code><tt> </tt><code class=scheme><span class=variable>udp-socket</span></code><code class=scheme>)</code> returns a synchronizable event
(see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>) that is in a blocking state when <code class=scheme>udp-send-to</code> on
<code class=scheme><span class=variable>udp-socket</span></code> would block.</p>
<p>
</p>
<li><p><a name="node_idx_2806"></a><a name="node_kw_definitionudp-receive-ready-evt"></a><code class=scheme>(udp-receive-ready-evt</code><tt> </tt><code class=scheme><span class=variable>udp-socket</span></code><code class=scheme>)</code> returns a synchronizable event
(see section <a href="mzscheme-Z-H-7.html#node_sec_7.7">7.7</a>) that is in a blocking state when
<code class=scheme>udp-receive!</code> on <code class=scheme><span class=variable>udp-socket</span></code> would block.</p>
<p>
</p>
<li><p><a name="node_idx_2808"></a><a name="node_kw_definitionudp-send-to-evt"></a><code class=scheme>(udp-send-to-evt</code><tt> </tt><code class=scheme><span class=variable>udp-socket hostname-address port-k
bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> returns a synchronizable event. The event is in
a blocking state when <code class=scheme>udp-send</code> on <code class=scheme><span class=variable>udp-socket</span></code> would
block. Otherwise, if the event is chosen in a synchronization, data
is sent as for <code class=scheme>(udp-send-to <code class=scheme><span class=variable>udp-socket</span></code>
<code class=scheme><span class=variable>hostname-address</span></code> <code class=scheme><span class=variable>port-k</span></code> <code class=scheme><span class=variable>bytes</span></code> <code class=scheme><span class=variable>start-k</span></code>
<code class=scheme><span class=variable>end-k</span></code>)</code>, and the synchronization result is void. (No bytes
are sent if the event is not chosen.)</p>
<p>
</p>
<li><p><a name="node_idx_2810"></a><a name="node_kw_definitionudp-send-evt"></a><code class=scheme>(udp-send-evt</code><tt> </tt><code class=scheme><span class=variable>udp-socket bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> is like
<code class=scheme>udp-send-to-evt</code>, except that <code class=scheme><span class=variable>udp-socket</span></code> must be
connected when the event is synchronized, and if the event is chosen
in a synchronization, the datagram goes to the connection target. If
<code class=scheme><span class=variable>udp-socket</span></code> is closed or unconnected, the
<a name="node_idx_2812"></a><code class=scheme>exn:fail:network</code> exception is raised during a synchronization attempt.</p>
<p>
</p>
<li><p><a name="node_idx_2814"></a><a name="node_kw_definitionudp-receive!-evt"></a><code class=scheme>(udp-receive!-evt</code><tt> </tt><code class=scheme><span class=variable>udp-socket bytes</span></code><tt> </tt>[<code class=scheme><span class=variable>start-k end-k</span></code>]<code class=scheme>)</code> returns
a synchronizable event. The event is in a blocking state when
<code class=scheme>udp-receive</code> on <code class=scheme><span class=variable>udp-socket</span></code> would block. Otherwise, if
the event is chosen in a synchronization, data is receive into
<code class=scheme><span class=variable>bytes</span></code> as for <code class=scheme>(udp-receive! <code class=scheme><span class=variable>udp-socket</span></code> <code class=scheme><span class=variable>bytes</span></code>
<code class=scheme><span class=variable>start-k</span></code> <code class=scheme><span class=variable>end-k</span></code>)</code>, and the synchronization result is a list
of three values, corresponding to the three results from
<code class=scheme>udp-receive!</code>. (No bytes are received and the <code class=scheme><span class=variable>bytes</span></code>
content is not modified if the event is not chosen.)</p>
<p>
</p>
</ul><p></p>
<p>
</p>
<p>
</p>
<div class=footnoterule><hr></div><p></p>
<div class=footnote><p><a name="node_footnote_27"></a><a href="#node_call_footnote_27"><sup><small>27</small></sup></a> 63 is
the same as <code class=scheme>(<code class=scheme>char->integer</code> <span class=selfeval>#\?</span>)</code>.</p>
<p><a name="node_footnote_28"></a><a href="#node_call_footnote_28"><sup><small>28</small></sup></a> Flushing is performed by the default port
read handler (see section <a href="#node_sec_11.2.6">11.2.6</a>) rather than by
<code class=scheme><code class=scheme>read</code></code> itself.</p>
<p><a name="node_footnote_29"></a><a href="#node_call_footnote_29"><sup><small>29</small></sup></a> This non-byte result is
<em>not</em> intended to return a character or <code class=scheme><code class=scheme>eof</code></code>; in
particular, <code class=scheme>read-char</code> raises an exception if it encounters a
non-byte from a port.</p>
<p><a name="node_footnote_30"></a><a href="#node_call_footnote_30"><sup><small>30</small></sup></a> More precisely, the procedure is used by the
default port read handler; see also section <a href="#node_sec_11.2.6">11.2.6</a>.</p>
<p><a name="node_footnote_31"></a><a href="#node_call_footnote_31"><sup><small>31</small></sup></a> A
temporary string of size <code class=scheme><span class=variable>k</span></code> is allocated while reading the
input, even if the size of the result is less than <code class=scheme><span class=variable>k</span></code>
characters.</p>
<p><a name="node_footnote_32"></a><a href="#node_call_footnote_32"><sup><small>32</small></sup></a> Only mid-stream <code class=scheme><code class=scheme>eof</code></code>s can be
committed. A <code class=scheme><code class=scheme>eof</code></code> when the port is exhausted does not
correspond to data in the stream.</p>
<p><a name="node_footnote_33"></a><a href="#node_call_footnote_33"><sup><small>33</small></sup></a> Assuming that the current
port display and write handlers are the default ones; see
section <a href="#node_sec_11.2.7">11.2.7</a> for more information.</p>
<p><a name="node_footnote_34"></a><a href="#node_call_footnote_34"><sup><small>34</small></sup></a> The
port read handler is not used for <code class=scheme>read/recursive</code> or
<code class=scheme>read-syntax/recursive</code>.</p>
<p><a name="node_footnote_35"></a><a href="#node_call_footnote_35"><sup><small>35</small></sup></a> Under Mac OS X, Finder aliases are zero-length
files.</p>
<p><a name="node_footnote_36"></a><a href="#node_call_footnote_36"><sup><small>36</small></sup></a> For MrEd, the executable path is the name of a
MrEd executable.</p>
<p><a name="node_footnote_37"></a><a href="#node_call_footnote_37"><sup><small>37</small></sup></a> Under Windows, <code class=scheme><code class=scheme>file-exists?</code></code> reports
<code class=scheme><span class=selfeval>#t</span></code> for all variations of the special filenames (e.g.,
<code class=scheme><span class=selfeval>"LPT1"</span></code>, <code class=scheme><span class=selfeval>"x:/baddir/LPT1"</span></code>).</p>
<p><a name="node_footnote_38"></a><a href="#node_call_footnote_38"><sup><small>38</small></sup></a> For FAT filesystems under
Windows, directories do not have modification dates. Therefore, the
creation date is returned for a directory (but the modification date
is returned for a file).</p>
<p><a name="node_footnote_39"></a><a href="#node_call_footnote_39"><sup><small>39</small></sup></a> MzScheme implements a listener with multiple
sockets, if necessary, to accomodate multiple addresses with
different protocol families. Under Linux,
if <code class=scheme><span class=variable>hostname-string-or-false</span></code> maps to both IPv4 and IPv6
addresses, then the behavior depends on whether IPv6 is supported and
IPv6 sockets can be configured to listen to only IPv6 connections: if
IPv6 is not supported or IPv6 sockets are not configurable, then the
IPv6 addresses are ignored; otherwise, each IPv6 listener accepts
only IPv6 connections.</p>
<p><a name="node_footnote_40"></a><a href="#node_call_footnote_40"><sup><small>40</small></sup></a> If <code class=scheme><span class=variable>hostname-string</span></code> is associated with
multiple addresses, they are tried one at a time until a connection
succeeds. The name <code class=scheme><span class=selfeval>"localhost"</span></code> generally specifies the local
machine.</p>
<p><a name="node_footnote_41"></a><a href="#node_call_footnote_41"><sup><small>41</small></sup></a> The TCP protocol does not include a ``no longer
reading'' state on connections, so <code class=scheme>tcp-abandon-port</code> is
equivalent to <code class=scheme>close-input-port</code> on input TCP ports.</p>
<p><a name="node_footnote_42"></a><a href="#node_call_footnote_42"><sup><small>42</small></sup></a> For most machines, the answer
corresponds to the current machine's only Internet address. But when
a machine serves multiple addresses, the result is
connection-specific.</p>
</div>
<div align=right class=navigation><i>[Go to <span><a href="mzscheme.html">first</a>, <a href="mzscheme-Z-H-10.html">previous</a></span><span>, <a href="mzscheme-Z-H-12.html">next</a></span> page<span>; </span><span><a href="mzscheme.html#node_toc_start">contents</a></span><span><span>; </span><a href="mzscheme-Z-H-22.html#node_index_start">index</a></span>]</i></div>
<p></p>
</div>
</body>
</html>
|