User defined pipe and redirection operators: Difference between revisions

Content added Content deleted
m (→‎{{header|Phix}}: added syntax colouring, marked p2js compatible (in distro))
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.: <lang bash>( head x & tail x & wait ) | grep test</lang>
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 ¢''
<lang bash>aa="$(
<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"</lang>
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'''
<lang algol68>MODE
<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);</lang>
=: = (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]]
<lang algol68> # Sample ''utilities'' PROCedure declarations #
<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:~;</lang>
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]]
<lang algol68># Sample ''pipe I/O'' OPerator declarations #
<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:~;</lang>
OP APPEND = (PAGEAPPEND page)YIELDLINE:~;</syntaxhighlight>
'''File: test_Iterator_pipe_page.a68'''
'''File: test_Iterator_pipe_page.a68'''
<lang algol68>#!/usr/local/bin/a68g --script #
<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}}==
<lang go>package main
<syntaxhighlight lang="go">package main


import (
import (
Line 425: Line 425:
fmt.Println(name, "not found")
fmt.Println(name, "not found")
}
}
}</lang>
}</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.


<lang j>require 'task'
<syntaxhighlight lang="j">require 'task'
data=:<;._2 shell 'lynx -dump -nolist -width=999 http://en.wikipedia.org/wiki/List_of_computer_scientists'</lang>
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:


<lang j>grep=: +./@E.S:0 # ]</lang>
<syntaxhighlight lang="j">grep=: +./@E.S:0 # ]</syntaxhighlight>


Step 2: select and display the required data:
Step 2: select and display the required data:


<lang j> ;'aa' grep 'ALGOL' grep 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:


<lang j> ;'aa' grep 'ALGOL' grep data,data
<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:


<lang j>declare=: erase@boxopen
<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</lang>
echo 'Pioneer:';aa</syntaxhighlight>


This produces the result:
This produces the result:


<lang>Pioneer: * Adriaan van Wijngaarden - Dutch pioneer; ARRA, ALGOL</lang>
<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().
<lang julia>const LISTDATA = """
<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()
</lang>{{out}}
</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.
<lang perl>use strict;
<syntaxhighlight lang="perl">use strict;
use 5.10.0;
use 5.10.0;


Line 794: Line 794:
;
;


print while $_ = $chain->readline;</lang>
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.
<!--<lang Phix>(phixonline)-->
<!--<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>
<!--</lang>-->
<!--</syntaxhighlight>-->
{{out}}
{{out}}
<pre>
<pre>
Line 967: Line 967:
=={{header|Racket}}==
=={{header|Racket}}==


<lang 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 perl6>sub cat ($fname) { lazy $fname.IO.lines };
<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";</lang>
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):
<lang tcl>package require Tcl 8.6
<syntaxhighlight lang="tcl">package require Tcl 8.6


# Helpers
# Helpers
Line 1,265: Line 1,265:
}
}
close $f
close $f
}</lang>
}</syntaxhighlight>
Sample pipeline:
Sample pipeline:
<lang tcl>set file "List_of_computer_scientists.lst"
<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"</lang>
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.
<lang ecmascript>import "./seq" for Lst
<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")</lang>
showCount.call("Number of scientists", "the_important_scientists.lst")</syntaxhighlight>


{{out}}
{{out}}