User defined pipe and redirection operators: Difference between revisions
Content added Content deleted
m (→{{header|Phix}}: added syntax colouring, marked p2js compatible (in distro)) |
Thundergnat (talk | contribs) m (syntax highlighting fixup automation) |
||
Line 18: | Line 18: | ||
* define the procedures: input(cmd,stream), pipe(stream,cmd), output(stream, stream), whereis(array), append(stream) |
* define the procedures: input(cmd,stream), pipe(stream,cmd), output(stream, stream), whereis(array), append(stream) |
||
For bonus Kudos: Implement the shell "&" concept as a dyadic operator in the specific language. e.g.: < |
For bonus Kudos: Implement the shell "&" concept as a dyadic operator in the specific language. e.g.: <syntaxhighlight lang="bash">( head x & tail x & wait ) | grep test</syntaxhighlight> |
||
'''Sample shell script:''' ''¢ draft - pending a better (more interesting) suggestion ¢'' |
'''Sample shell script:''' ''¢ draft - pending a better (more interesting) suggestion ¢'' |
||
< |
<syntaxhighlight lang="bash">aa="$( |
||
( |
( |
||
head -4 < List_of_computer_scientists.lst; |
head -4 < List_of_computer_scientists.lst; |
||
Line 28: | Line 28: | ||
) | sort | uniq | tee the_important_scientists.lst | grep aa |
) | sort | uniq | tee the_important_scientists.lst | grep aa |
||
); |
); |
||
echo "Pioneer: $aa"</ |
echo "Pioneer: $aa"</syntaxhighlight> |
||
'''Input Records:''' |
'''Input Records:''' |
||
{|class="wikitable" style="text-align: center; margin: 1em auto 1em auto;" |
{|class="wikitable" style="text-align: center; margin: 1em auto 1em auto;" |
||
Line 90: | Line 90: | ||
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of Currying.}} |
{{wont work with|ELLA ALGOL 68|Any (with appropriate job cards) - tested with release [http://sourceforge.net/projects/algol68/files/algol68toc/algol68toc-1.8.8d/algol68toc-1.8-8d.fc9.i386.rpm/download 1.8-8d] - due to extensive use of Currying.}} |
||
'''File: Iterator_pipe_operators.a68''' |
'''File: Iterator_pipe_operators.a68''' |
||
< |
<syntaxhighlight lang="algol68">MODE |
||
PAGEIN = PAGE, |
PAGEIN = PAGE, |
||
PAGEAPPEND = REF PAGE, |
PAGEAPPEND = REF PAGE, |
||
Line 110: | Line 110: | ||
>> = (GENLINE gen, PAGEAPPEND page)VOID: gen(APPEND page), |
>> = (GENLINE gen, PAGEAPPEND page)VOID: gen(APPEND page), |
||
=: = (GENLINE gen, FILTER filter)GENLINE: filter(gen), |
=: = (GENLINE gen, FILTER filter)GENLINE: filter(gen), |
||
=: = (GENLINE gen, MANYTOONE cmd)GENLINE: cmd(gen);</ |
=: = (GENLINE gen, MANYTOONE cmd)GENLINE: cmd(gen);</syntaxhighlight> |
||
'''File: Iterator_pipe_utilities.a68''' |
'''File: Iterator_pipe_utilities.a68''' |
||
* c.f. [[User defined pipe and redirection operators/ALGOL 68#Iterator pipe utilities]] |
* c.f. [[User defined pipe and redirection operators/ALGOL 68#Iterator pipe utilities]] |
||
< |
<syntaxhighlight lang="algol68"> # Sample ''utilities'' PROCedure declarations # |
||
PROC cat = ([]GENLINE argv)GENLINE:~; |
PROC cat = ([]GENLINE argv)GENLINE:~; |
||
PROC tee = ([]YIELDLINE args filter)FILTER:~; |
PROC tee = ([]YIELDLINE args filter)FILTER:~; |
||
Line 120: | Line 120: | ||
PROC sort = (GENLINE arg)GENLINE:~; |
PROC sort = (GENLINE arg)GENLINE:~; |
||
PROC head = (INT n, []GENLINE args)GENLINE:~; |
PROC head = (INT n, []GENLINE args)GENLINE:~; |
||
PROC tail = (INT n, []GENLINE args)GENLINE:~;</ |
PROC tail = (INT n, []GENLINE args)GENLINE:~;</syntaxhighlight> |
||
'''File: Iterator_pipe_page.a68''' |
'''File: Iterator_pipe_page.a68''' |
||
* c.f. [[User defined pipe and redirection operators/ALGOL 68#Iterator pipe page]] |
* c.f. [[User defined pipe and redirection operators/ALGOL 68#Iterator pipe page]] |
||
< |
<syntaxhighlight lang="algol68"># Sample ''pipe I/O'' OPerator declarations # |
||
OP READ = (PAGEIN page)GENLINE:~; |
OP READ = (PAGEIN page)GENLINE:~; |
||
OP WRITE = (PAGEOUT page)YIELDLINE: ~; |
OP WRITE = (PAGEOUT page)YIELDLINE: ~; |
||
OP APPEND = (PAGEAPPEND page)YIELDLINE:~;</ |
OP APPEND = (PAGEAPPEND page)YIELDLINE:~;</syntaxhighlight> |
||
'''File: test_Iterator_pipe_page.a68''' |
'''File: test_Iterator_pipe_page.a68''' |
||
< |
<syntaxhighlight lang="algol68">#!/usr/local/bin/a68g --script # |
||
# First define what kind of record (aka LINE) we are piping and filtering # |
# First define what kind of record (aka LINE) we are piping and filtering # |
||
FORMAT line fmt = $xg$; |
FORMAT line fmt = $xg$; |
||
Line 182: | Line 182: | ||
"Number of scientists: ", whole( UPB the scientists list, 0 ), newline |
"Number of scientists: ", whole( UPB the scientists list, 0 ), newline |
||
)) |
)) |
||
</syntaxhighlight> |
|||
</lang> |
|||
'''Output:''' |
'''Output:''' |
||
<pre> |
<pre> |
||
Line 191: | Line 191: | ||
=={{header|Go}}== |
=={{header|Go}}== |
||
< |
<syntaxhighlight lang="go">package main |
||
import ( |
import ( |
||
Line 425: | Line 425: | ||
fmt.Println(name, "not found") |
fmt.Println(name, "not found") |
||
} |
} |
||
}</ |
}</syntaxhighlight> |
||
Output: |
Output: |
||
<pre> |
<pre> |
||
Line 439: | Line 439: | ||
Step 0: get the data. The task does not specify how to get the data, so here I use lynx, which is readily available on most unix-like systems, including cygwin. Note that lynx needs to be in the OS PATH when running j. |
Step 0: get the data. The task does not specify how to get the data, so here I use lynx, which is readily available on most unix-like systems, including cygwin. Note that lynx needs to be in the OS PATH when running j. |
||
< |
<syntaxhighlight lang="j">require 'task' |
||
data=:<;._2 shell 'lynx -dump -nolist -width=999 http://en.wikipedia.org/wiki/List_of_computer_scientists'</ |
data=:<;._2 shell 'lynx -dump -nolist -width=999 http://en.wikipedia.org/wiki/List_of_computer_scientists'</syntaxhighlight> |
||
Step 1: define task core algorithms: |
Step 1: define task core algorithms: |
||
< |
<syntaxhighlight lang="j">grep=: +./@E.S:0 # ]</syntaxhighlight> |
||
Step 2: select and display the required data: |
Step 2: select and display the required data: |
||
< |
<syntaxhighlight lang="j"> ;'aa' grep 'ALGOL' grep data |
||
* Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL |
* Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL |
||
</syntaxhighlight> |
|||
</lang> |
|||
As for the concept of a pipe that presents data one record at a time to a downstream function, that corresponds to the J operator <code>@</code> and we could achieve the "left to right" syntax mechanism by explicitly ordering its arguments <code>2 :'v@u'</code> but it's not clear how to demonstrate that usefully, in this task. (And, I could write a lot of code, to accomplish what's being accomplished here with the two successive greps, but I find that concept distasteful and tedious.) |
As for the concept of a pipe that presents data one record at a time to a downstream function, that corresponds to the J operator <code>@</code> and we could achieve the "left to right" syntax mechanism by explicitly ordering its arguments <code>2 :'v@u'</code> but it's not clear how to demonstrate that usefully, in this task. (And, I could write a lot of code, to accomplish what's being accomplished here with the two successive greps, but I find that concept distasteful and tedious.) |
||
Line 456: | Line 456: | ||
However, note also that J's sort (<code>/:~</code>) and uniq (<code>~.</code>) operations would work just fine on this kind of data. For example: |
However, note also that J's sort (<code>/:~</code>) and uniq (<code>~.</code>) operations would work just fine on this kind of data. For example: |
||
< |
<syntaxhighlight lang="j"> ;'aa' grep 'ALGOL' grep data,data |
||
* Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL |
* Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL |
||
* Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL |
* Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL |
||
Line 462: | Line 462: | ||
;'aa' grep ~. 'ALGOL' grep data,data |
;'aa' grep ~. 'ALGOL' grep data,data |
||
* Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL |
* Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL |
||
</syntaxhighlight> |
|||
</lang> |
|||
That said, this implements most (perhaps all) of the required complexities: |
That said, this implements most (perhaps all) of the required complexities: |
||
< |
<syntaxhighlight lang="j">declare=: erase@boxopen |
||
tee=: 4 :0 |
tee=: 4 :0 |
||
if._1=nc boxopen x do.(x)=: '' end. |
if._1=nc boxopen x do.(x)=: '' end. |
||
Line 506: | Line 506: | ||
) |
) |
||
echo 'Pioneer:';aa</ |
echo 'Pioneer:';aa</syntaxhighlight> |
||
This produces the result: |
This produces the result: |
||
<lang>Pioneer: * Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL</ |
<syntaxhighlight lang="text">Pioneer: * Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL</syntaxhighlight> |
||
=={{header|Julia}}== |
=={{header|Julia}}== |
||
Uses Julia's Channels as asynchronous pipes. Note that the $( .. ) Unix command, which gathers stdin output into a single variable, is not used. Instead, a common output channel for various tasks is used to gather output. Sort() rather than sort() is used so as not to overload Base.sort(). |
Uses Julia's Channels as asynchronous pipes. Note that the $( .. ) Unix command, which gathers stdin output into a single variable, is not used. Instead, a common output channel for various tasks is used to gather output. Sort() rather than sort() is used so as not to overload Base.sort(). |
||
< |
<syntaxhighlight lang="julia">const LISTDATA = """ |
||
Wil van der Aalst business process management, process mining, Petri nets |
Wil van der Aalst business process management, process mining, Petri nets |
||
Hal Abelson intersection of computing and teaching |
Hal Abelson intersection of computing and teaching |
||
Line 684: | Line 684: | ||
Sort(commonoutchan) |> uniq() |> tee("the_important_scientists.lst") |> |
Sort(commonoutchan) |> uniq() |> tee("the_important_scientists.lst") |> |
||
grep("aa") |> print_lines() |
grep("aa") |> print_lines() |
||
</ |
</syntaxhighlight>{{out}} |
||
<pre> |
<pre> |
||
Adriaan van Wijngaarden Dutch pioneer; ARRA, ALGOL |
Adriaan van Wijngaarden Dutch pioneer; ARRA, ALGOL |
||
Line 691: | Line 691: | ||
=={{header|Perl}}== |
=={{header|Perl}}== |
||
Implementing only stream chaining, cat, grep and tee. Oddly enough, I don't feel the urge to implement all of the more-or-less-the-same features asked for by the task. |
Implementing only stream chaining, cat, grep and tee. Oddly enough, I don't feel the urge to implement all of the more-or-less-the-same features asked for by the task. |
||
< |
<syntaxhighlight lang="perl">use strict; |
||
use 5.10.0; |
use 5.10.0; |
||
Line 794: | Line 794: | ||
; |
; |
||
print while $_ = $chain->readline;</ |
print while $_ = $chain->readline;</syntaxhighlight> |
||
=={{header|Phix}}== |
=={{header|Phix}}== |
||
Line 803: | Line 803: | ||
The distributed version also has a couple of alternatives for pipe_head() and pipe_tail(), along with a |
The distributed version also has a couple of alternatives for pipe_head() and pipe_tail(), along with a |
||
class-less version that is compatible with pwa/p2js. |
class-less version that is compatible with pwa/p2js. |
||
<!--< |
<!--<syntaxhighlight lang="phix">(phixonline)--> |
||
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Fake_Redirection.exw</span> |
<span style="color: #000080;font-style:italic;">-- demo\rosetta\Fake_Redirection.exw</span> |
||
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- class (see other version in distro)</span> |
<span style="color: #008080;">without</span> <span style="color: #008080;">js</span> <span style="color: #000080;font-style:italic;">-- class (see other version in distro)</span> |
||
Line 957: | Line 957: | ||
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span> |
<span style="color: #0000FF;">{}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">wait_key</span><span style="color: #0000FF;">()</span> |
||
<span style="color: #7060A8;">abort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
<span style="color: #7060A8;">abort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">)</span> |
||
<!--</ |
<!--</syntaxhighlight>--> |
||
{{out}} |
{{out}} |
||
<pre> |
<pre> |
||
Line 967: | Line 967: | ||
=={{header|Racket}}== |
=={{header|Racket}}== |
||
< |
<syntaxhighlight lang="racket"> |
||
#lang racket |
#lang racket |
||
Line 1,099: | Line 1,099: | ||
(require 'sample) |
(require 'sample) |
||
</syntaxhighlight> |
|||
</lang> |
|||
=={{header|Raku}}== |
=={{header|Raku}}== |
||
Line 1,109: | Line 1,109: | ||
This assumes that the data is in a tab separated file "List_of_computer_scientists.lst" in the current directory. |
This assumes that the data is in a tab separated file "List_of_computer_scientists.lst" in the current directory. |
||
<lang |
<syntaxhighlight lang="raku" line>sub cat ($fname) { lazy $fname.IO.lines }; |
||
sub head ($count, @positional) { @positional.head($count) } |
sub head ($count, @positional) { @positional.head($count) } |
||
sub redirect ($fname) { cat($fname) } |
sub redirect ($fname) { cat($fname) } |
||
Line 1,128: | Line 1,128: | ||
).flat .sort .unique tee 'the_important_scientists.lst') .grep: /'aa'/; |
).flat .sort .unique tee 'the_important_scientists.lst') .grep: /'aa'/; |
||
say "Pioneer: $aa";</ |
say "Pioneer: $aa";</syntaxhighlight> |
||
{{out}} |
{{out}} |
||
<pre>Pioneer: Adriaan van Wijngaarden Dutch pioneer; ARRA, ALGOL</pre> |
<pre>Pioneer: Adriaan van Wijngaarden Dutch pioneer; ARRA, ALGOL</pre> |
||
Line 1,134: | Line 1,134: | ||
=={{header|Tcl}}== |
=={{header|Tcl}}== |
||
The syntax of redirections is slightly out, as they're inserted as explicit pipeline elements, and standard Tcl syntax is used to pull in results from sub-pipelines (because it is vastly simpler): |
The syntax of redirections is slightly out, as they're inserted as explicit pipeline elements, and standard Tcl syntax is used to pull in results from sub-pipelines (because it is vastly simpler): |
||
< |
<syntaxhighlight lang="tcl">package require Tcl 8.6 |
||
# Helpers |
# Helpers |
||
Line 1,265: | Line 1,265: | ||
} |
} |
||
close $f |
close $f |
||
}</ |
}</syntaxhighlight> |
||
Sample pipeline: |
Sample pipeline: |
||
< |
<syntaxhighlight lang="tcl">set file "List_of_computer_scientists.lst" |
||
set aa [pipeline \ |
set aa [pipeline \ |
||
<< [pipeline < $file | head 4] [pipeline < $file | grep ALGOL | tee "ALGOL_pioneers.txt"] [pipeline < $file | tail 4] \ |
<< [pipeline < $file | head 4] [pipeline < $file | grep ALGOL | tee "ALGOL_pioneers.txt"] [pipeline < $file | tail 4] \ |
||
| sort | uniq | tee "the_important_scientists.lst" | grep aa] |
| sort | uniq | tee "the_important_scientists.lst" | grep aa] |
||
puts "Pioneer: $aa"</ |
puts "Pioneer: $aa"</syntaxhighlight> |
||
=={{header|Wren}}== |
=={{header|Wren}}== |
||
Line 1,277: | Line 1,277: | ||
{{libheader|Wren-seq}} |
{{libheader|Wren-seq}} |
||
Although Wren supports operator overloading, there are a number of restrictions which would make simulating the Unix shell operators awkward or even imposible. As in the Phix (and Go) examples, I've therefore used named methods instead. |
Although Wren supports operator overloading, there are a number of restrictions which would make simulating the Unix shell operators awkward or even imposible. As in the Phix (and Go) examples, I've therefore used named methods instead. |
||
< |
<syntaxhighlight lang="ecmascript">import "./seq" for Lst |
||
var FS = {} // fake file system |
var FS = {} // fake file system |
||
Line 1,378: | Line 1,378: | ||
System.write("Pioneer: %(FS["aa"])") |
System.write("Pioneer: %(FS["aa"])") |
||
showCount.call("Number of ALGOL pioneers", "ALGOL_pioneers.lst") |
showCount.call("Number of ALGOL pioneers", "ALGOL_pioneers.lst") |
||
showCount.call("Number of scientists", "the_important_scientists.lst")</ |
showCount.call("Number of scientists", "the_important_scientists.lst")</syntaxhighlight> |
||
{{out}} |
{{out}} |