Questions tagged «programming-languages»

与编程语言的设计,实现和分析有关的问题。不适用于有关如何编程的问题,该问题不在本网站上。

6
编程语言,正则表达式和形式语言之间的关系是什么
我在网上四处寻找这个问题的答案,似乎每个人都隐含地知道答案,除了我。据推测,这是因为唯一关心的人是受过该学科高等教育的人。另一方面,我却被高中作业深深吸引。 我的问题是,编程语言与形式语言到底有什么关系?在我读过的任何地方,都说着类似“形式语言用于定义编程语言语法”的内容。 现在,根据我的能力,正式语言是一系列适用于一组特定符号(该语言的字母)的生产规则。这些生产规则定义了一组转换,例如: b -> a aaa->c 可以这样应用: abab->aaaa aaaa-> ca 顺便提一句,如果我们将形式语言的字母定义为{a,b,c},则a和b是非终结符,而c是终结符,因为它不能转换(如果我错了,请纠正我那)。 那么,考虑到所有这些,这到底在编程语言中有什么用呢?通常还会指出,正则表达式用于解析其文本形式的语言,以确保语法正确。这很有道理。然后说明正则表达式是由正式语言定义的。正则表达式返回true或false(至少以我的经验),这取决于代表正则表达式的有限状态自动机是否达到目标点。据我所知,这与转换无关。 对于程序本身的编译,我认为一种形式语言可以将代码转换为连续的较低级别的代码,并最终通过一组复杂的规则到达汇编,然后硬件可以理解这些规则。 从我的困惑来看,这就是事实。我所说的内容可能有很多根本上的错误,这就是为什么我要寻求帮助。 *除非您认为某条(a|b)*b*c->true规则类似于生产规则,否则在这种情况下该规则需要一个有限状态自动机(即regex)。就像我们刚才说的那样,这没有任何意义

3
什么是分阶段功能(概念上)?
在CACM的最新文章[1]中,作者提出了分阶段功能的实现。他们使用该术语好像它是众所周知的,并且所有参考文献似乎都不是显而易见的介绍。 他们给了一个简短的解释(重点是我的和参考编号已更改;原来是22) 在程序生成的上下文中,由Taha和Sheard [2]建立的多级编程(MSP,简称暂存)允许程序员显式地将程序表达式的求值延迟到较晚的阶段(因此,暂存一个表达式)。当前阶段有效地充当代码生成器,该代码生成器组成(并可能执行)下一阶段的程序。 但是,塔哈(Taha)和谢德(Sheard)写道(重点是我): 多阶段程序是一个涉及代码生成,编译和执行的程序,所有程序都在同一进程内。多阶段语言表示多阶段程序。暂存以及因此的多阶段编程可满足对通用解决方案的需求,而这些通用解决方案无需支付运行时的解释性开销。 然后,他们继续引用了一些较旧的作品,据称这些作品表明分期是有效的,这表明该概念更古老。他们没有为该术语本身提供参考。 这些陈述似乎是正交的,即使不是矛盾的。也许Rompf和Odersky写的是Taha和Sheard提出的应用,但也许是对同一件事的另一种看法。他们似乎同意,重要的一点是程序会在运行时重新编写其自身的部分,但是我不知道这是否是必要的和/或足够的能力。 那么,什么是分期分别在此背景下举办的解释?这个词从哪里来? 轻量级模块化分段: T. Rompf和M. Odersky(2012)的一种实用方法,用于生成运行时代码和编译DSL W. Taha和T.Sheard(2000)的带有显式注释的MetaML和多阶段编程

3
SML中的函子和范畴论之间有什么关系?
与Andrej Bauer在此答案中的陈述相同的想法 Haskell社区开发了许多受类别理论启发的技术,其中最著名的是monad,但不应将其与monad混淆。 之间是什么关系仿函数的SML和函子范畴论? 由于我不了解其他语言(例如Haskell或OCaml)中函子的详细信息,因此,如果有有价值的信息,请同时添加其他语言的部分。

2
是否有任何编程语言都使用通用递归函数作为基础?
这是一个幼稚的问题,因此可能是畸形的问题,因此请您提前道歉! 我的观点是,图灵机可以看作是过程/命令式编程语言的计算基础。同样,lambda演算是函数式编程语言的基础。 我最近了解到,Church-Turing论文还显示了与第三种计算模型的等效性:通用递归函数。是否有任何编程语言将其用作其计算模型?如果不是,是否有技术原因?即,除了“没有人尝试过”之外?

8
每个表达式都有意义的编程语言
根据建议,我将从Stack Overflow重新发布。 最近,我一直在考虑以下问题。 考虑标准“ Hello world!”的代码。程序: main() { printf("Hello World"); } 现在,此代码中的几乎任何更改都将使其完全无用,实际上,几乎所有更改都会阻止代码进行编译。例如: main(5 { printf("Hello World"); } 现在到实际的问题。是否存在一种编程语言,其中每种符号的可能组合(即每种表达式)都有意义?我尝试考虑某种解决方案,并提出了两种解决方案: 后缀数量有限。基本上,在编写任何代码之前,所有变量都已经定义好了,您只需要使用它们。从理论上讲,您可以通过形成许多简单程序的链来执行任意数量的操作,每个简单程序将结果馈给其他程序。代码可以用后缀符号表示为一系列字符。 “ Postfix”带有一堆变量。变量存储在堆栈中;每个操作从顶部开始取两个变量,并将结果放在它们的位置。程序在到达最后一个操作或变量时结束。 我个人讨厌这两个。它们不仅局限,而且优雅。它们甚至不是真正的解决方案,更像是变通方法,本质上是将某些工作“外包”到外部流程中。 有谁有其他想法如何解决这个问题?

10
是否可以为所有计算机提供通用汇编语言?
我想问一些关于汇编语言的问题。我的理解是,它与机器语言非常接近,从而使其更快,更高效。 由于我们存在不同的计算机体系结构,这是否意味着我必须在Assembly中针对不同的体系结构编写不同的代码?如果是这样,为什么汇编不写一次-到处运行类型的语言?简单地使其具有通用性,只编写一次就可以在几乎任何具有不同配置的机器上运行,难道不是一件容易的事吗?(我认为这是不可能的,但是我想提出一些具体,深入的答案) 有人可能会说C是我要寻找的语言。我以前没有使用过C,但是我认为它仍然是一种高级语言,尽管可能比Java快。我可能在这里错了。

4
垃圾收集器如何避免堆栈溢出?
因此,我在考虑垃圾收集器的工作方式,并想到了一个有趣的问题。大概垃圾收集器必须以相同的方式遍历所有结构。他们不知道正在遍历链表或平衡树之类的天气。他们也不会在搜索中消耗过多的内存。我想到遍历所有结构的一种可能方法,也是唯一的方法,可能就是像使用二叉树那样递归遍历所有结构。但是,这会在链表甚至平衡差的二叉树上产生堆栈溢出。但是我曾经使用过的所有垃圾收集语言似乎都没有问题的处理能力。 在龙书中,它使用各种“未扫描”队列。基本上,而不是递归遍历结构,它只是将需要标记的内容添加到队列中,然后针对未标记的所有内容将其删除。但是这个队列不会很大吗? 那么,垃圾收集器如何遍历任意结构?这种遍历技术如何避免溢出?

3
类型系统的分类(强/弱,动态/静态)
简而言之:如何在学术环境中对类型系统进行分类;尤其是在哪里可以找到使不同类型的类型系统之间的区别清晰的信誉良好的来源? 从某种意义上说,这个问题的难点不是我找不到答案,而是我可以找到太多答案,而且没有一个能脱颖而出。背景是我正在尝试改进Has​​kell Wiki上有关输入的文章,该文章目前具有以下区别: 没有类型:语言没有类型的概念,或者从类型的角度来看:语言中只有一种类型。汇编语言只有“位模式”类型,Rexx和Tk只有“文本”类型,核心MatLab只有“复杂值矩阵”类型。 弱类型输入:只有很少的可分辨类型,可能还有几种类型的类型同义词。例如,C使用整数表示布尔值,整数,字符,位集和枚举。 强类型:细粒度的类型集,例如Ada,Wirthian语言(Pascal,Modula-2),Eiffel 这完全与我的个人看法相反,后者更像是: 弱类型输入:对象具有类型,但是在上下文需要时会隐式转换为其他类型。例如,Perl,PHP和JavaScript都是"1"可以在或多或少可以使用的任何上下文中使用的语言1。 强类型化:对象具有类型,并且没有隐式转换(尽管可以使用重载来模拟它们),因此在错误的上下文中使用对象是错误的。在Python中,用字符串或浮点数索引数组会引发TypeError异常;在Haskell中,它将在编译时失败。 我从其他比我更富有经验的人那里征求意见,有人对此进行了描述: 弱类型输入:对数据执行无效操作不会受到控制或拒绝,而只会产生无效/任意结果。 强类型:仅当数据与操作兼容时才允许对数据进行操作。 据我了解,第一个和最后一个特征将称为C弱类型,第二个将其称为强类型。第一个和第二个将Perl和PHP称为弱类型,第三个将它们称为强类型。这三个都将Python描述为强类型。 我认为大多数人会告诉我“嗯,没有共识,没有公认的条款含义”。如果这些人都错了,我很高兴听到这个消息,但如果他们是对的,那么如何做 CS的研究人员描述和比较类型的系统?我可以使用哪种问题较少的术语? 作为一个相关的问题,我觉得动态/静态区别通常是用“编译时间”和“运行时间”来表示的,考虑到是否编译语言并不是该语言的本质,我发现这并不令人满意。作为其实现。我觉得应该对动态类型和静态类型进行纯粹的语义描述。类似于“静态语言是可以在其中键入每个子表达式的语言”。我希望您能提出任何使这种概念更加清楚的想法,特别是参考文献。

1
do-while循环足以满足图灵完整性吗?
我知道,在命令式编程语言中,while-do循环足以构成使图灵完成的语言的控制流构造(就控制流而言,当然,我们还需要无限制的内存和某些运算符...) 。我的问题的要点是:do-while循环是否具有与while-do-循环相同的计算能力?换句话说,如果不可能完全跳过指令,那么一种语言可以是图灵完备的吗? 我意识到这里的某些语义可能有点模棱两可,所以让我用一个特定的例子来表达实际问题: Brainfuck(BF)是一个图灵tarpit,其中唯一的控制流是while-do循环,表示为[...](问题的底部有一个完整的语言规范,以防您不熟悉Brainfuck。让我们定义一种新的语言BF *,它,.+-<>的语义与BF中的语义相同,但是代替它的[]是{},它具有do-while循环。也就是说,与BF的唯一区别是每个循环至少可以执行一次,然后才能跳过进一步的迭代。 BF *图灵完成了吗?如果是这样,我会对如何将BF转换为BF *感兴趣。如果不是,我该如何证明? 我自己的一些观察: 并非每个BF程序都可以转换为BF *。例如,不可能用BF *编写可能会或可能不会读取或打印值的程序-如果该程序可能打印一个或多个值,它将始终打印至少一个。但是,可能存在BF的图灵完备子集,可以将其转换为BF *。 我们不能简单地将[f](f仅由组成的任意Brainbrauck程序翻译成+-[]<>)(以消除第一次迭代的效果),因为a)并非每个可计算的函数都具有可计算的逆,并且b)即使有,循环次数不一定会比因此少,因此不能保证首先递归地执行此步骤。f-1{f}f-1f 这是Brainfuck语言的快速概述。Brainfuck在无限磁带上操作,其中每个单元包含一个字节值,最初为零。溢出会回绕,因此增加255可得到0,反之亦然。该语言包含8条指令: + Increment the current cell. - Decrement the current cell. > Move tape head to the right. < Move tape head to the left. , Input a character from STDIN into the current cell. . …

5
为什么图灵功能语言完整?
也许我对这个主题的有限理解是错误的,但这是我到目前为止所了解的: 函数式编程基于Alonzo Church制定的Lambda微积分。 命令式编程基于教会学生Alan Turing制作的Turing机器模型。 Lambda演算的功能和图灵机一样强大, 这意味着它们的计算能力相当。 如果函数式编程基于Lambda演算而不是Turing机器,那么为什么其中某些(或全部)描述为Turing完整,而不是Lambda完整或类似的东西?“图灵完备性”一词在图灵机上是否有任何特殊之处,还是仅此一个词? 最后,如果命令式语言基于Turing Machine,而计算机基本上是Turing计算机,没有无限的内存,这是否意味着它们在我们现代PC上的性能优于功能编程语言? 如果是这样的话,那么lambda演算机器的等效条件是什么? 我知道这似乎是3个独立的问题,但它们都是紧密相关的,并且每个问题都取决于前一个问题是否是有效的问题。


7
Unix / C中不一致和不完整的例子有哪些?
在理查德·加布里埃尔(Richard Gabriel)的著名文章《更糟的崛起》中,他将MIT / Stanford(Lisp)和新泽西(C / Unix)设计哲学的漫画版本沿简单性,正确性,一致性和完整性进行了对比。他举例说明了“ PC失败者的问题”(Josh Haberman在其他地方讨论过),以为Unix优先于实现的简单性而不是接口的简单性。 我想出的另一个例子是不同的数字方法。Lisp可以表示任意大的数字(最大取决于内存的大小),而C将数字限制为固定的位数(通常为32-64)。我认为这说明了正确性轴。 有什么例子可以保持一致性和完整性?以下是加百列的所有描述(他承认是漫画): 麻省理工学院/斯坦福大学的方法 简单性-设计必须在实现和界面上都简单。接口要比实现简单,这一点更为重要。 正确性-设计在所有可观察的方面都必须正确。根本不允许不正确。 一致性-设计一定不能不一致。为了避免不一致,允许设计稍微简单一些,不太完整。一致性与正确性一样重要。 完整性-设计必须涵盖尽可能多的重要情况。必须涵盖所有合理预期的情况。不允许过分简化完整性。 新泽西州方法 简单性-设计必须在实现和界面上都简单。简单的实现比接口更重要。简洁是设计中最重要的考虑因素。 正确性-设计在所有可观察的方面都必须正确。简单比正确要好一些。 一致性-设计一定不能过分不一致。在某些情况下,为了简化起见,可以牺牲一致性,但是最好将设计中处理不常见情况的那些部分放掉,而不是引入实现复杂性或不一致。 完整性-设计必须涵盖尽可能多的重要情况。所有合理预期的情况都应包括在内。可以牺牲完整性来支持任何其他质量。实际上,每当实现简单性受到威胁时,都必须牺牲完整性。如果保持简单性,可以牺牲一致性来实现完整性。尤其是一文不值的是接口的一致性。 请注意,我并不是在问Gabriel是否正确(这个问题不适用于StackExchange),而是要举例说明他可能一直在指的是什么。

3
什么时候两个模拟不是双模拟?
给定一个标记的过渡系统 ,其中小号是一组状态,Λ是一组标签,并→ ⊆ 小号× Λ × 小号是三元关系。与往常一样,写入p α →交通 q为(p ,α ,q )∈ →交通。将标记的过渡p α →交通 q表示在状态中的系统p改变状态到q与标签(S,Λ ,→ )(S,Λ,→)(S,\Lambda,\to)小号SSΛΛ\Lambda→交通⊆小号× Λ × S→⊆S×Λ×S\to\subseteq S\times\Lambda\times Sp →αqp→αqp \stackrel\alpha\rightarrow q(p ,α ,q)∈ →(p,α,q)∈→(p,\alpha,q)\in\top →αqp→αqp\stackrel\alpha\to qpppqqq,表示 α是引起状态变化的一些可观察动作。αα\alphaαα\alpha 现在关系被一个称为模拟当且仅当 ∀ (p ,q )∈ [R , 如果 p α →交通 p ' 然后 ∃ q ',ř …

3
类型'a->'b的ML函数
我们的教授要求我们考虑OCaml中具有以下类型的函数 'a -> 'b 即,一个参数的函数可以是任何东西,并且可以返回不同的任何东西。 我想到了raise在忽略其参数的函数中使用: let f x = raise Exit 但是这位教授说,有一种解决方案不需要标准库中的任何功能。我很困惑:'b如果一开始就没有一个,怎么办? 我在这里而不是在Stack Overflow上问是因为我想了解发生了什么,我不想只看一个没有解释的程序。

2
类型检查算法
我正在开始有关类型检查算法的个人书目研究,并需要一些技巧。最常用的类型检查算法,策略和通用技术是什么? 我对以众所周知的强静态类型化语言(例如C ++,Java 5 +,Scala或其他语言)实现的复杂类型检查算法特别感兴趣。IE,由于基础语言的键入非常简单(例如Java 1.4及更低版本),因此类型检查算法不是很简单。 我本身对特定的语言X,Y或Z并不感兴趣。我对类型检查算法感兴趣,无论它们针对的是哪种语言。如果您提供诸如“您从未听说过的语言L是强类型且类型复杂的答案”,则可以使用类型检查算法,该算法通过使用算法Z检查X和Y来进行A,B和C运算,或者“用于Scala的策略X和Y以及用于C#的A的变体Z都很酷,因为R,S和T功能以这种方式起作用”,那么答案就很好。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.