|
46 | 46 | Tangler filename=examples/ex3.flx
|
47 | 47 | Extension=.flx
|
48 | 48 | flx ....
|
49 |
| -Tangle id=ex4 |
50 |
| -Tangler filename=examples/ex4.flx |
51 |
| -Extension=.flx |
52 |
| -flx .... |
53 |
| -Tangle id=ex4 |
54 |
| -Tangler filename=examples/ex4.flx |
55 |
| -Extension=.flx |
56 |
| -flx .... |
57 |
| -Tangle id=ex4 |
58 |
| -Tangler filename=examples/ex4.flx |
59 |
| -Extension=.flx |
60 |
| -flx .... |
61 |
| -Tangle id=ex4 |
62 |
| -Tangler filename=examples/ex4.flx |
63 |
| -Extension=.flx |
64 |
| -flx .... |
65 |
| -Tangle id=ex4 |
66 |
| -Tangler filename=examples/ex4.flx |
67 |
| -Extension=.flx |
68 |
| -flx .... |
69 | 49 | <html><head>
|
70 | 50 | <style type="text/css">
|
71 | 51 | body {margin:3%; }
|
|
384 | 364 | "Asynchronous I/O",
|
385 | 365 | "Felix is a coroutine",
|
386 | 366 | "Running subsystems",
|
387 |
| -"The concept of fibration", |
388 |
| -"next", |
389 |
| -"high", |
390 |
| -"med1", |
391 |
| -"med2", |
392 |
| -"med3", |
393 |
| -"low" |
| 367 | +"The concept of fibration" |
394 | 368 | ];
|
395 | 369 | function expand_all(dummy)
|
396 | 370 | {
|
|
468 | 442 | </div>
|
469 | 443 | <div class=m1 onclick="mshow('menu4','#The concept of fibration_h')"> <a href="#The_concept_of_fibration_h">The concept of fibration</a></div>
|
470 | 444 | <div class=sm id=menu4>
|
471 |
| - <div class=m2><a href="#next_h">next</a></div> |
472 |
| - </div> |
473 |
| - <div class=m1 onclick="mshow('menu5','#high_h')"> <a href="#high_h">high</a></div> |
474 |
| - <div class=sm id=menu5> |
475 |
| - <div class=m2><a href="#med1_h">med1</a></div> |
476 |
| - <div class=m2><a href="#med2_h">med2</a></div> |
477 |
| - <div class=m2><a href="#med3_h">med3</a></div> |
478 | 445 | </div>
|
479 |
| - <script>counter_max=5;</script> |
| 446 | + <script>counter_max=4;</script> |
480 | 447 | </div>
|
481 | 448 | <!--End Left Margin Toc-->
|
482 | 449 |
|
@@ -728,92 +695,14 @@ <h1 id='A_low_level_example._h'><img src='/share/src/web/images/minus.gif' id='A
|
728 | 695 | when there is nothing left to do precisely because it's just another
|
729 | 696 | coroutine.
|
730 | 697 | </p></div><h2 id='Running_subsystems_h'><img src='/share/src/web/images/minus.gif' id='Running subsystems' onclick='toggle(this,"Running_subsystems_d")' alt='+'/> 3.2 Running subsystems</h2><div id='Running_subsystems_d' style='display:block'>
|
731 |
| -<p>So far we have worked with the main scheduler, which terminates when there |
732 |
| -is nothing left to do. So I want to show you a little problem and |
733 |
| -how to solve it: |
734 |
| -</p><pre class='inclusion'> |
735 |
| -examples/ex4.flx</pre> |
736 |
| -<p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="big_keyword" title="Define a mutable variable">var</span> x = <span class="library" title="functional, singly linked list">list</span>[<span class="library" title="binding of C int type">int</span>] (1,2,3,4,5); |
737 |
| -<span class="lineno" id=line2></span> <span class="big_keyword" title="Define a function with no side-effects">fun</span> addup (acc: <span class="library" title="binding of C int type">int</span>) (elt:<span class="library" title="binding of C int type">int</span>) => acc + elt; |
738 |
| -<span class="lineno" id=line3></span> <span class="big_keyword" title="Define a mutable variable">var</span> y = <span class="library" title="accumulated values of data structure from left into initial value using function">fold_left</span> addup 0 x; |
739 |
| -<span class="lineno" id=line4></span> <span class="library" title="Print a string to standard output with newline appended">println</span>$ y; |
740 |
| -</pre></p><p>This is the purely functional way to add up a list. It is a client server application |
741 |
| -where the fold operation is the service provider and the <code>addup</code> |
742 |
| -function is the client. However the technical implementation has a severe |
743 |
| -problem: the client if forced to write a function to do the work, which can |
744 |
| -only handle one element at a time, and has a single state variable, <code>acc</code>, |
745 |
| -the accumulator. In other words, the client has to provide a callback, |
746 |
| -which is a slave to master fold routine. |
747 |
| -</p><p>Here is another way to do the same thing: |
748 |
| -</p><pre class='inclusion'> |
749 |
| -examples/ex4.flx</pre> |
750 |
| -<p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="big_keyword" title="Define a mutable variable">var</span> acc = 0; |
751 |
| -<span class="lineno" id=line2></span> <span class="small_keyword" title="for loop">for</span> elt <span class="small_keyword" title="membership operator, function mem">in</span> x <span class="small_keyword" title="imperative code begins">do</span> |
752 |
| -<span class="lineno" id=line3></span> acc = acc + elt; |
753 |
| -<span class="lineno" id=line4></span> <span class="small_keyword" title="end of body">done</span> |
754 |
| -</pre></p><p>In this case we're using an iterator over the list which is provided |
755 |
| -by the library, and that iterator is a slave to the client code |
756 |
| -which is master: the iterator is called by the client. |
757 |
| -</p><p>Both these solutions work, and they are in fact dual or <em>control inverse</em>: |
758 |
| -each one is the other one turned inside out with respect to control relations. |
759 |
| -The client is a slave in the first solution whilst the iterator is a slave |
760 |
| -in the second. |
761 |
| -</p><p>There is way to do this without slavery .. using coroutines of course! |
762 |
| -</p><pre class='inclusion'> |
763 |
| -examples/ex4.flx</pre> |
764 |
| -<p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="small_keyword" title="end of extension">begin</span> |
765 |
| -<span class="lineno" id=line2></span> chip adder connector io pin inp: %<<span class="library" title="binding of C int type">int</span> { |
766 |
| -<span class="lineno" id=line3></span> <span class="big_keyword" title="Define a mutable variable">var</span> acc = 0; |
767 |
| -<span class="lineno" id=line4></span> <span class="small_keyword" title="while loop">while</span> <span class="library" title="truth value">true</span> <span class="small_keyword" title="imperative code begins">do</span> |
768 |
| -<span class="lineno" id=line5></span> <span class="big_keyword" title="Define a mutable variable">var</span> elt = read io.inp; |
769 |
| -<span class="lineno" id=line6></span> acc = acc + elt; |
770 |
| -<span class="lineno" id=line7></span> <span class="library" title="Print a string to standard output with newline appended">println</span>$ acc; |
771 |
| -<span class="lineno" id=line8></span> <span class="small_keyword" title="end of body">done</span> |
772 |
| -<span class="lineno" id=line9></span> } |
773 |
| -<span class="lineno" id=line10></span> (source_from_list x |-> adder)(); |
774 |
| -<span class="lineno" id=line11></span> <span class="small_keyword" title="end of extension">end</span> |
775 |
| -</pre></p><p>The chip <code>source_from_list</code> comes from the standard library, it just writes |
776 |
| -each element of a list down its output channel. |
777 |
| -</p><p>The code terminates when you expect and the last result printed is the answer. |
778 |
| -But we just want the answer! |
779 |
| -</p><p>So here is our first attempt: |
780 |
| -</p><pre class='inclusion'> |
781 |
| -examples/ex4.flx</pre> |
782 |
| -<p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="small_keyword" title="end of extension">begin</span> |
783 |
| -<span class="lineno" id=line2></span> <span class="big_keyword" title="Define a mutable variable">var</span> acc = 0; |
784 |
| -<span class="lineno" id=line3></span> chip adder connector io pin inp: %<<span class="library" title="binding of C int type">int</span> { |
785 |
| -<span class="lineno" id=line4></span> <span class="small_keyword" title="while loop">while</span> <span class="library" title="truth value">true</span> <span class="small_keyword" title="imperative code begins">do</span> |
786 |
| -<span class="lineno" id=line5></span> sleep (0.025); |
787 |
| -<span class="lineno" id=line6></span> <span class="big_keyword" title="Define a mutable variable">var</span> elt = read io.inp; |
788 |
| -<span class="lineno" id=line7></span> acc = acc + elt; |
789 |
| -<span class="lineno" id=line8></span> <span class="small_keyword" title="end of body">done</span> |
790 |
| -<span class="lineno" id=line9></span> } |
791 |
| -<span class="lineno" id=line10></span> |
792 |
| -<span class="lineno" id=line11></span> (source_from_list x |-> adder)(); |
793 |
| -<span class="lineno" id=line12></span> <span class="library" title="Print a string to standard output with newline appended">println</span>$ <span class="fstring">"Attempt1: "</span> + acc.<span class="library" title="Convert a value to a string">str</span>; |
794 |
| -<span class="lineno" id=line13></span> <span class="small_keyword" title="end of extension">end</span> |
795 |
| -</pre></p><p>Of course this doesn't work we get: |
796 |
| -</p><p><pre class="prefmtbg">Attempt1: 0 |
797 |
| -</pre></p><p>because as we know, the mainline is a coroutine, and it continues on whilst |
798 |
| -the <code>adder</code> is sleeping. In the abstract semantics when there is a set |
799 |
| -of coroutines waiting to run, the scheduler can run <em>any one</em> of them |
800 |
| -so even without the sleep, it could complete the mainline before completing |
801 |
| -the pipeline. |
802 |
| -</p><pre class='inclusion'> |
803 |
| -examples/ex4.flx</pre> |
804 |
| -<p><pre class='flxbg'><span class="lineno" id=line1></span> <span class="small_keyword" title="end of extension">begin</span> |
805 |
| -<span class="lineno" id=line2></span> <span class="big_keyword" title="Define a mutable variable">var</span> acc = 0; |
806 |
| -<span class="lineno" id=line3></span> chip adder connector io pin inp: %<<span class="library" title="binding of C int type">int</span> { |
807 |
| -<span class="lineno" id=line4></span> <span class="small_keyword" title="while loop">while</span> <span class="library" title="truth value">true</span> <span class="small_keyword" title="imperative code begins">do</span> |
808 |
| -<span class="lineno" id=line5></span> <span class="big_keyword" title="Define a mutable variable">var</span> elt = read io.inp; |
809 |
| -<span class="lineno" id=line6></span> acc = acc + elt; |
810 |
| -<span class="lineno" id=line7></span> <span class="small_keyword" title="end of body">done</span> |
811 |
| -<span class="lineno" id=line8></span> } |
812 |
| -<span class="lineno" id=line9></span> |
813 |
| -<span class="lineno" id=line10></span> run (source_from_list x |-> adder); |
814 |
| -<span class="lineno" id=line11></span> <span class="library" title="Print a string to standard output with newline appended">println</span>$ <span class="fstring">"Attempt2: "</span> + acc.<span class="library" title="Convert a value to a string">str</span>; |
815 |
| -<span class="lineno" id=line12></span> <span class="small_keyword" title="end of extension">end</span> |
816 |
| -</pre></p></div></div><h1 id='The_concept_of_fibration_h'><img src='/share/src/web/images/minus.gif' id='The concept of fibration' onclick='toggle(this,"The_concept_of_fibration_d")' alt='+'/> 4 The concept of fibration</h1><div id='The_concept_of_fibration_d' style='display:block'> |
| 698 | +<p>There is a constraint on Felix coroutines: they have to be procedures. |
| 699 | +Functions cannot read and write channels. However there is a way around |
| 700 | +this problem: you can use the <code>run</code> subroutine to create an run a new, |
| 701 | +nested, scheduler. |
| 702 | +</p><p>The <code>run</code> subroutine, being a subroutine, returns when it is finished. |
| 703 | +</p><p>Unfortunately there is another constraint on nested schedulers: they cannot |
| 704 | +do asynchronous I/O. |
| 705 | +</p></div></div><h1 id='The_concept_of_fibration_h'><img src='/share/src/web/images/minus.gif' id='The concept of fibration' onclick='toggle(this,"The_concept_of_fibration_d")' alt='+'/> 4 The concept of fibration</h1><div id='The_concept_of_fibration_d' style='display:block'> |
817 | 706 | <p>A <em>coroutine system</em> is a collection of processes called <em>fibres</em>
|
818 | 707 | with these properties:
|
819 | 708 | <ul>
|
@@ -874,60 +763,7 @@ <h1 id='A_low_level_example._h'><img src='/share/src/web/images/minus.gif' id='A
|
874 | 763 | </p><p>In addition, I/O transfers always result in the reader proceeding,
|
875 | 764 | to give it a chance to actually fetch the data before the write
|
876 | 765 | might modify it.
|
877 |
| -</p><h2 id='next_h'><img src='/share/src/web/images/minus.gif' id='next' onclick='toggle(this,"next_d")' alt='+'/> 4.1 next</h2><div id='next_d' style='display:block'> |
878 |
| -<p>stuff |
879 |
| -</p><p><pre class='flxbg'><span class="lineno" id=line1></span> blah |
880 |
| -</pre></p><p>stuff |
881 |
| -</p></div></div><h1 id='high_h'><img src='/share/src/web/images/minus.gif' id='high' onclick='toggle(this,"high_d")' alt='+'/> 5 high</h1><div id='high_d' style='display:block'> |
882 |
| -<p>blam |
883 |
| -</p><h2 id='med1_h'><img src='/share/src/web/images/minus.gif' id='med1' onclick='toggle(this,"med1_d")' alt='+'/> 5.1 med1</h2><div id='med1_d' style='display:block'> |
884 |
| -<p>stuff |
885 |
| -stuff |
886 |
| -stuff |
887 |
| -stuff |
888 |
| -stuff |
889 |
| -stuff |
890 |
| -stuff |
891 |
| -stuff |
892 |
| -stuff |
893 |
| -stuff |
894 |
| -stuff |
895 |
| -stuff |
896 |
| -stuff |
897 |
| -stuff |
898 |
| -stuff |
899 |
| -stuff |
900 |
| -stuff |
901 |
| -stuff |
902 |
| -stuff |
903 |
| -stuff |
904 |
| -stuff |
905 |
| -stuff |
906 |
| -stuff |
907 |
| -stuff |
908 |
| -stuff |
909 |
| -stuff |
910 |
| -stuff |
911 |
| -stuff |
912 |
| -stuff |
913 |
| -stuff |
914 |
| -stuff |
915 |
| -stuff |
916 |
| -stuff |
917 |
| -stuff |
918 |
| -stuff |
919 |
| -stuff |
920 |
| -</p></div><h2 id='med2_h'><img src='/share/src/web/images/minus.gif' id='med2' onclick='toggle(this,"med2_d")' alt='+'/> 5.2 med2</h2><div id='med2_d' style='display:block'> |
921 |
| -<p>stuff |
922 |
| -</p></div><h2 id='med3_h'><img src='/share/src/web/images/minus.gif' id='med3' onclick='toggle(this,"med3_d")' alt='+'/> 5.3 med3</h2><div id='med3_d' style='display:block'> |
923 |
| -<p>stuff <em>inline html works</em> |
924 |
| -but we have <code>micros</code> for inline code as well. |
925 |
| -<a href= https://www.itkservices2.com/nem_review_1.2>See ITK stuff</a> |
926 |
| -</p><h3 id='low_h'><img src='/share/src/web/images/minus.gif' id='low' onclick='toggle(this,"low_d")' alt='+'/> 5.3.1 low</h3><div id='low_d' style='display:block'> |
927 |
| -<p>level 3 stuff |
928 |
| -</p><p><pre class='flxbg'><span class="lineno" id=line1></span> blah |
929 |
| -</pre></p><p>stuff |
930 |
| -</p></div></div></div><!--Main Content Body End--> |
| 766 | +</p></div><!--Main Content Body End--> |
931 | 767 |
|
932 | 768 | </div> <!-- rightpanel contents end -->
|
933 | 769 | <hr>
|
|
0 commit comments