Language agnostic 为什么不';我能在大多数高级语言中看到管道操作符吗?

Language agnostic 为什么不';我能在大多数高级语言中看到管道操作符吗?,language-agnostic,programming-languages,concurrency,shell,pipe,Language Agnostic,Programming Languages,Concurrency,Shell,Pipe,在unixshell中,编程是一个非常强大的工具。通过一小部分核心实用程序、一种系统语言(如C)和一种脚本语言(如Python),您可以构造非常紧凑、功能强大的shell脚本,这些脚本由操作系统自动并行化 很明显,这是一个非常强大的编程范例,但除了shell脚本之外,我还没有将管道视为任何语言中的第一类抽象。使用管道复制脚本功能所需的代码似乎总是相当复杂 所以我的问题是,为什么我在现代高级语言(如C#、Java等)中看不到类似于Unix管道的东西。?是否有支持一流管道的语言(shell脚本除外)

在unixshell中,编程是一个非常强大的工具。通过一小部分核心实用程序、一种系统语言(如C)和一种脚本语言(如Python),您可以构造非常紧凑、功能强大的shell脚本,这些脚本由操作系统自动并行化

很明显,这是一个非常强大的编程范例,但除了shell脚本之外,我还没有将管道视为任何语言中的第一类抽象。使用管道复制脚本功能所需的代码似乎总是相当复杂

所以我的问题是,为什么我在现代高级语言(如C#、Java等)中看不到类似于Unix管道的东西。?是否有支持一流管道的语言(shell脚本除外)?这难道不是一种方便、安全的并发算法表达方式吗

为了防止有人提起它,我看了F#pipe forward操作符(forward pipe操作符),它看起来更像一个函数应用程序操作符。据我所知,它将函数应用于数据,而不是将两个流连接在一起,但我愿意接受更正


Postscript:在对实现协同程序进行一些研究时,我意识到存在某些相似之处。在一篇文章中,Martin Wolf描述了一个与我类似的问题,但是在协同程序而不是管道方面

您可以在C#和Java中找到类似管道的东西,例如,您可以将一个连接流放入另一个连接流的构造函数中

因此,在Java中有:

new BufferedReader(new InputStreamReader(System.in));

您可能需要查找链接输入流或输出流。

您可以在Erlang中非常轻松地执行管道类型并行。下面是我2008年1月的博客文章的无耻复制/粘贴

此外,允许并行函数组合,这相当于相同的事情,给您隐式并行化

你已经考虑过了 管道-gzcat怎么样 foo.tar.gz | tar xf-“?你不可以 我早就知道了,但贝壳是 在中运行解压和解压 并行-标准输入刚刚读入焦油 阻塞,直到数据通过 gzcat

很多任务都可以表达出来 在管道方面,如果可以的话 这样做,然后获得一定程度的 对David来说,并行化很简单 国王的助手代码(即使在erlang中 节点(即机器):

所以基本上他在这里做的是 列出步骤-每个步骤 以有趣的方式实施 接受前面的任何内容作为输入 阶跃输出(FUN甚至可以 定义(当然)。去检查 大卫要出去吃饭了 代码和更详细的解释


我认为最根本的原因是因为C#和Java往往被用来构建更多的单片系统。从文化上讲,想要做类似管道的事情并不常见——您只需要让应用程序实现必要的功能。构建大量简单工具,然后以任意方式将它们粘合在一起的想法在这些环境中并不常见

如果你看看一些脚本语言,比如Python和Ruby,有一些很好的工具可以在这些脚本中完成类似管道的事情。例如,查看Python子流程模块,它允许您执行以下操作:

proc = subprocess.Popen('cat -',
                       shell=True,
                       stdin=subprocess.PIPE,
                       stdout=subprocess.PIPE,)
stdout_value = proc.communicate('through stdin to stdout')[0]
print '\tpass through:', stdout_value

Objective-C具有类。我经常使用它。

通常你不需要它,没有它程序运行得更快

管道基本上是消费者/生产者模式。写下这些消费者和生产者并不难,因为他们共享的数据不多

  • Python的管道:
  • Mozart OZ可以使用端口和线程制作管道

我在用Python构建管道函数方面有很多乐趣。我有一个我写的库,我把内容和一个样本运行。最适合我的是XML处理,如本文所述。

哈哈!感谢我的谷歌富,我发现你可能会感兴趣。基本上,答案与“除非必须,否则不要重载运算符”的论点相反,通过重载按位OR运算符来提供类似shell的管道,从而产生如下Python代码:

for i in xrange(2,100) | sieve(2) | sieve(3) | sieve(5) | sieve(7):
    print i
从概念上讲,它所做的是通过一个筛选函数将数字列表从2输送到99(
xrange(2100)
),该筛选函数删除给定数字的倍数(先2,然后3,然后5,然后7)。这是素数生成器的开始,尽管以这种方式生成素数是一个相当糟糕的主意。但我们可以做得更多:

for i in xrange(2,100) | strify() | startswith(5):
    print i
这将生成范围,然后将所有范围从数字转换为字符串,然后过滤掉任何不以5开头的内容

文章显示了一个基本的父类,它允许您重载两个方法,
map
filter
,来描述管道的行为。因此
strify()


它非常聪明,虽然这可能意味着它不是很像python,但它展示了您所追求的,以及一种可以轻松应用于其他语言的技术。

感谢所有伟大的答案和评论,以下是我所学到的总结:

事实证明,有一个完整的范例与我感兴趣的东西有关,叫做。下面是专门为基于流的编程设计的语言的一个很好的例子。Hartamnn管道概括了Unix和其他操作系统中使用的流和管道的思想,允许多个输入和输出流(而不仅仅是一个输入流和两个输出流)。包含功能强大的抽象,使以类似管道的方式表示并发进程变得容易。Java提供和,可与线程一起使用以实现相同的抽象
for i in xrange(2,100) | strify() | startswith(5):
    print i
rnorm(100) %>% abs %>% mean
iris %>%
  filter(Species == "virginica") %>%
  select(-Species) %>%
  colMeans
help?> |>
search: |>

  |>(x, f)


  Applies a function to the preceding argument. This allows for easy function chaining.

  Examples
  ≡≡≡≡≡≡≡≡≡≡

  julia> [1:5;] |> x->x.^2 |> sum |> inv
  0.01818181818181818