天道酬勤,学无止境

Elixir 和 Julia 之类的语言在什么意义上是同音的?(In what sense are languages like Elixir and Julia homoiconic?)

问题

Lisp 中的同质性很容易看出:

(+ 1 2)

既是以12作为参数对+的函数调用,也是包含+12的列表。 它同时是代码和数据。

但是,在像 Julia 这样的语言中:

1 + 2

我知道我们可以在 Julia 中将其解析为Expr

:(1 + 2)

然后我们可以获取 AST 并对其进行操作:

julia> Meta.show_sexpr(:(1+2)) (:call, :+, 1, 2)

因此,我们可以在 Julia(和 Elixir)中操作程序的 AST。 但是它们是否与 Lisp 具有相同的意义——任何代码片段真的只是语言本身的数据结构吗?

我看不出 Julia 中的1 + 2类的代码是如何立即成为数据的,而 Lisp 中的(+ 1 2)只是一个列表。 那它还是谐音吗?

回答1

用比尔克林顿的话来说,“这取决于‘是’这个词的含义是什么”。 好吧,不是真的,但这确实取决于“homoiconic”一词的含义。 这个词有足够的争议,我们不再说 Julia 是 homoiconic——所以你可以自己决定它是否符合条件。 我将引用 Kent Pitman(对 Lisp 略知一二)在 2001 年的 Slashdot 采访中所说的话,而不是试图定义同质性:

我喜欢 Lisp 愿意代表自己。 人们经常将其解释为它代表自己的能力,但我认为这是错误的。 大多数语言都能够表示自己,但他们根本没有意愿。 Lisp 程序由列表表示,程序员知道这一点。 如果它是数组也没关系。 所表示的是程序结构,而不是字符语法,这很重要,但除此之外,选择是相当随意的。 表示是否为 Right® 选择并不重要。 重要的是它是一个共同的、商定的选择,以便可以有一个丰富的程序操作程序社区,这些程序在这个共同的表示中“做交易”。

他也没有定义同质性——他可能和我一样不想进入一个定义性的争论。 但他切入了问题的核心:一种语言有多愿意代表自己? Lisp 在极端情况下是愿意的——你甚至无法避免它:程序作为数据的表示就在那里,盯着你的脸。 Julia 不使用 S 表达式语法,因此代码作为数据的表示不太明显,但隐藏的并不深:

julia> ex = :(2a + b + 1)
:(2a + b + 1)

julia> dump(ex)
Expr
  head: Symbol call
  args: Array(Any,(4,))
    1: Symbol +
    2: Expr
      head: Symbol call
      args: Array(Any,(3,))
        1: Symbol *
        2: Int64 2
        3: Symbol a
      typ: Any
    3: Symbol b
    4: Int64 1
  typ: Any

julia> Meta.show_sexpr(ex)
(:call, :+, (:call, :*, 2, :a), :b, 1)

julia> ex.args[3]
:b

julia> ex.args[3] = :(3b)
:(3b)

julia> ex
:(2a + 3b + 1)

Julia 代码由Expr类型(以及符号和原子)表示,虽然表面语法和结构之间的对应关系不太明显,但它仍然存在。 更重要的是,人们知道代码只是可以生成和操作的数据,因此正如 KMP 所说,存在“丰富的程序操作程序社区”。

这不仅仅是将 Julia 代码作为数据结构的表面呈现——这也是 Julia 向自身表示其代码的方式。 当您在 REPL 中输入表达式时,它会被解析为Expr对象。 然后将这些Expr对象传递给eval ,这将它们“降低”为更常规的Expr对象,然后将这些对象传递给类型推断,所有这些都在 Julia 中实现。 关键是编译器使用与您看到的完全相同的代码表示。 在 Lisp 中情况并没有那么不同。 当您查看 Lisp 代码时,您实际上并没有看到列表对象——它们只存在于计算机的内存中。 您看到的是列表文字的文本表示,Lisp 解释器将其解析并转换为列表对象,然后对其进行评估,就像 Julia 一样。 Julia 的语法可以看作是Expr文字的文本表示Expr恰好是一种比列表更不通用的数据结构。

我不知道细节,但我怀疑 Elixir 是相似的——也许 José 会插话。

更新 (2019)

在过去 4 年多的时间里,我更多地考虑了这一点,我认为 Lisp 和 Julia 之间的主要区别在于:

  • 在 Lisp 中,代码的语法与用于表示该代码的数据结构的语法相同。
  • 在 Julia 中,代码的语法与表示该代码的数据结构的语法完全不同。

为什么这很重要? 在支持 Julia 的一方,人们喜欢事物的特殊语法,并且经常发现 S-expression 语法不方便或令人不快。 在亲 Lisp 方面,当您尝试生成的数据结构(表示代码)的语法与您通常编写的代码的语法相同时,弄清楚如何正确进行元编程要容易得多. 这就是为什么当人们尝试在 Julia 中编写宏时,最好的建议之一是执行以下操作:

  1. 编写您希望宏生成的代码类型的示例
  2. 对该代码调用Meta.@dump以将其视为数据结构
  3. 编写代码来生成该数据结构——这是您的宏。

在 Lisp 中,您不必执行第 2 步,因为代码的语法已经与数据结构的语法相同。 在 Julia 中有 quasiquoting(在 Lisp 中) quote ... end:(...)构造,它们允许您使用代码语法构造数据结构,但这仍然不如让它们使用相同的语法那么直接首先。

也可以看看:

  • https://docs.julialang.org/en/v1/manual/metaprogramming/
  • Julia 中的“符号”是什么?

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 朱莉娅是什么“符号”?(What is a “symbol” in Julia?)
    问题 具体来说:我正在尝试使用Julia的DataFrames包,特别是将readtable()函数与names选项一起使用,但这需要符号向量。 什么是符号? 他们为什么会选择一个字符串向量呢? 到目前为止,我只发现了少量的茱莉亚语中的“符号”一词的引用。 似乎符号用“:var”表示,但是我对它们的含义还很不清楚。 撇开:我可以跑步 df = readtable( "table.txt", names = [symbol("var1"), symbol("var2")] ) 我的两个项目符号问题仍然存在。 回答1 Julia中的符号与Lisp,Scheme或Ruby中的符号相同。 但是,我认为,对这些相关问题的回答并不十分令人满意。 如果您阅读了这些答案,似乎符号与字符串不同的原因是字符串是可变的,而符号是不可变的,符号也被“ interned”(无论如何)。 字符串在Ruby和Lisp中确实是可变的,但在Julia中却不是,并且实际上是红鲱鱼。 插入符号的事实(即,由语言实现进行哈希处理以进行快速相等比较)也是不相关的实现细节。 您可以实现不使用符号的实现,并且语言完全相同。 那么,什么是符号呢? 答案在于Julia和Lisp的共同点-能够将语言代码表示为语言本身的数据结构。 有些人称之为“同质性”(Wikipedia),但另一些人似乎并不认为单单就足以使一种语言具有同质性。
  • 词形化与词干的区别是什么?(What is the difference between lemmatization vs stemming?)
    问题 什么时候使用每个? 另外... NLTK词素化是否取决于词类? 如果不是,它会更准确吗? 回答1 简短而密集:http://nlp.stanford.edu/IR-book/html/htmledition/stemming-and-lemmatization-1.html 词干和词根化的目的都是将单词的屈折形式和有时与派生相关的形式减少为通用的基本形式。 但是,这两个词的风格不同。 词干通常是指粗略的启发式过程,它会砍掉单词的结尾,以期在大多数时间正确实现此目标,并且通常包括删除派生词缀。 词法词化通常是指使用单词的词汇和词法分析来正确处理事情,通常旨在仅去除词尾变化并返回单词的基数或字典形式,这被称为引理。 从NLTK文档中: 合法化和词干提取是规范化的特殊情况。 他们为一组相关的单词形式确定规范的代表。 回答2 合法化与阻止密切相关。 不同之处在于,词干分析器在不了解上下文的情况下对单个单词进行操作,因此无法根据词性区分具有不同含义的单词。 但是,茎杆通常更易于实现且运行速度更快,而降低的精度对于某些应用程序可能并不重要。 例如: “更好”一词的引理是“好”。 由于需要字典查找,因此茎干会漏掉​​此链接。 单词“ walk”是单词“ walking”的基本形式,因此,它在词干和词根化过程中都是匹配的。 根据上下文,单词“ meeting”可以是名词的基本形式
  • In what sense are languages like Elixir and Julia homoiconic?
    Homoiconicity in Lisp is easy to see: (+ 1 2) is both the function call to + with 1, 2 as arguments, as well as being a list containing +, 1, and 2. It is simultaneously both code and data. In a language like Julia, though: 1 + 2 I know we can parse this into an Expr in Julia: :(1 + 2) And then we can get the AST and manipulate it: julia> Meta.show_sexpr(:(1+2)) (:call, :+, 1, 2) So, we can manipulate a program's AST in Julia (and Elixir). But are they homoiconic in the same sense as Lisp- is any snippet of code really just a data structure in the language itself? I don't see how code like 1 +
  • Elixir变量真的是不可变的吗?(Are Elixir variables really immutable?)
    问题 在Dave Thomas的《 Programming Elixir》一书中,他指出“ Elixir强制执行不可变数据”,并继续说: 在Elixir中,一旦变量引用了[1,2,3]之类的列表,就知道它将始终引用那些相同的值(直到重新绑定该变量)。 这听起来像“除非您进行更改,否则它永远不会更改”,因此我对可变性和重新绑定之间的区别感到困惑。 突出差异的示例将非常有帮助。 回答1 不变性意味着数据结构不会改变。 例如,函数HashSet.new返回一个空集合,只要您坚持对该集合的引用,它就永远不会成为非空的。 不过,您可以在Elixir中做的是丢弃对某些内容的可变引用,然后将其重新绑定到新引用。 例如: s = HashSet.new s = HashSet.put(s, :element) s # => #HashSet<[:element]> 如果您没有显式重新绑定它,那么该引用下的值将发生更改,这是不可能发生的: s = HashSet.new ImpossibleModule.impossible_function(s) s # => #HashSet<[:element]> will never be returned, instead you always get #HashSet<[]> 将此与Ruby进行对比,您可以在其中执行以下操作: s = Set.new s
  • IO monad是否在像C#这样的语言中有意义?(Does an IO monad make sense in a language like C#)
    问题 在花了很多时间阅读和思考之后,我想我终于掌握了什么是monad,它们如何工作以及对它们有什么用。 我的主要目标是弄清楚monads是否可以应用到C#的日常工作中。 当我开始学习monad时,给人的印象是它们很神奇,它们以某种方式使IO和其他非纯函数纯净。 我了解monad对于.Net中的LINQ之类的重要性,并且Maybe对于处理不返回有效值的函数非常有用。 而且我也很高兴有必要限制代码中的有状态性并隔离外部依赖关系,我希望monads也会对这些有所帮助。 但是我最后得出的结论是,IO和处理状态的monad是Haskell的必要条件,因为Haskell没有其他方法可以做到这一点(否则,您不能保证排序,某些调用将被优化。)但是对于更主流的语言,单子语法并不适合这些需求,因为大多数语言已经可以轻松处理和声明和IO。 因此,我的问题是,可以说IO monad实际上仅在Haskell中有用吗? 是否有充分的理由在C#中实现IO monad? 回答1 我经常使用Haskell和F#,但从未真正感觉像在F#中使用IO或状态单子。 对我而言,主要原因是在Haskell中,您可以从某种类型中得知它不使用IO或状态,而这是非常有价值的信息。 在F#(和C#)中,对其他人的代码没有这种一般的期望,因此,将这种规范添加到自己的代码中不会给您带来太大的好处,并且您将为此付出一些常规开”
  • 如何通过指定模块和方法名称在 Elixir 中动态调用方法?(How to call a method dynamically in Elixir, by specifying both module and method name?)
    问题 我想知道 elixir 中的方法名称到底是什么: array = [1,2,3] module_name = :lists method_name = :nth # this not working module_name.method_name(1, array) # error, undef function lists.method_name/2 module_name.nth(1, array) # returns 1, module_name is OK. It's an atom 但是我可以在 erlang 中做几乎同样的事情: A = [1,2,3]. X = lists. Y = nth. X:Y(1,A). # returns 1 我怎么能在长生不老药中做到这一点? 回答1 您可以使用apply/3 ,它只是:erlang.apply/3的包装器。 它只是从带有参数数组的模块中调用给定的函数。 由于您将参数作为模块和函数名称传递,因此您可以使用变量。 apply(:lists, :nth, [1, [1,2,3]]) apply(module_name, method_name, [1, array]) 如果您想更多地了解 elixir 如何处理函数调用(以及其他所有内容),您应该查看quote和unquote 。 contents = quote do
  • 集合中的数量,长度和大小(count vs length vs size in a collection)
    问题 通过使用多种编程语言和库,我注意到用于集合中元素总数的各种术语。 最常见的似乎是length , count和size 。 例如。 array.length vector.size() collection.count 是否有任何首选的术语可以使用? 它取决于收集的类型吗? IE。 可变/不变的 是否首选将其作为属性而不是方法? 回答1 Length()倾向于引用连续的元素-例如,字符串具有长度。 Count()倾向于引用一个较松散的集合中的元素数。 Size()倾向于引用集合的大小,在矢量(或字符串)之类的情况下,长度通常可能与长度不同,字符串中可能有10个字符,但保留了20个字符。它也可以引用到元素数量-检查源/文档。 Capacity() -用于专门引用集合中分配的空间,而不是其中的有效元素数。 如果类型同时定义了“容量”和“大小”,则“大小”通常是指实际元素的数量。 我认为重点在于人类语言和习惯用语,字符串的大小似乎不太明显,而集合的长度同样令人困惑,即使它们可能用于指代同一事物(元素数量) )中的数据。 回答2 FWIW(几乎消失了),我更喜欢使用“ Count”,因为它似乎表明它将毫无疑问地返回集合中的元素/项目数。 当面对“长度”或“大小”这两个术语时,我常常想知道(或者甚至被迫重新阅读文档)片刻的东西是要告诉我集合中有多少元素,或者如何集合消耗的字节数。
  • 在Go中使用指针有什么意义?(What's the point of having pointers in Go?)
    问题 我知道Go中的指针允许函数参数的突变,但是如果它们仅采用引用(带有适当的const或可变限定符),会不会更简单。 现在,我们有了指针,并且对于某些内置类型(例如,映射和通道)进行隐式按引用传递。 我是否缺少某些东西,或者Go中的指针仅仅是不必要的复杂性? 回答1 我真的很喜欢从http://www.golang-book.com/8摘录的示例 func zero(x int) { x = 0 } func main() { x := 5 zero(x) fmt.Println(x) // x is still 5 } 与之相反 func zero(xPtr *int) { *xPtr = 0 } func main() { x := 5 zero(&x) fmt.Println(x) // x is 0 } 回答2 指针之所以有用,有几个原因。 指针允许控制内存布局(影响CPU缓存的效率)。 在Go中,我们可以定义一个结构,其中所有成员都位于连续内存中: type Point struct { x, y int } type LineSegment struct { source, destination Point } 在这种情况下, Point结构嵌入LineSegment结构中。 但是您不能总是直接嵌入数据。 如果要支持二进制树或链表之类的结构,则需要支持某种指针。
  • 朱莉娅是动态输入的吗?(Is Julia dynamically typed?)
    问题 许多博客和手册本身都说Julia是动态键入的。 但是,从我对手册的阅读中,听起来更像是使用类型推断(例如F#)静态键入的。 朱莉娅是否使用类型推断静态键入? 它是动态输入的吗? 我假设它是动态键入的,手册似乎不太可能是错误的。 朱莉娅完全涉及类型推断吗? 回答1 蒂姆·霍利(Tim Holy)的答案很正确,但我会详细说明。 首先,让我们定义一些术语–您可能不同意我的定义,但至少您会知道我在说什么。 在我看来,静态和动态语言之间的主要区别在于:在静态语言中,表达式具有类型;在静态语言中,表达式具有类型。 在动态语言中,值具有类型。 在静态语言中,有一些规则可以确定程序中每个表达式的类型。 表达式的类型决定了程序的行为。 不允许为每个表达式确定一致类型的程序被认为是错误的,将无法编译。 在存在多态性的情况下,表达式的类型可能不是单一的具体类型:参数多态性可以被认为是一种让相同代码描述整个具体类型化算法家族的方法,该算法由类型的参数索引; 可以将子类型多态性视为将有限数量的动态行为引入了其他静态语言中。 另一方面,动态语言没有为表达式分配类型的规则:数据在执行时流经程序的方式暗含了类型。 通常,表达式可能根本会产生任何类型的值。 因此,类型理论家有时将动态语言描述为“单型”-即从静态角度来看,“类型”本质上是表达式的属性,而动态语言中的所有表达式都具有Any类型。 当然
  • 碾压Python!为什么Julia速度这么快?
    什么要选择 Julia?因为它比其他脚本语言更快,它在具备 Python、MATLAB、R 语言开发速度的同时,又能生成与 C 语言和 Fortran 一样快的代码。但 Julia 新手对这种说法可能会有点怀疑。 为什么其他脚本语言不也提升一下速度?Julia 可以做到的,为什么其他脚本语言做不到?你能提供基准测试来证明它的速度吗?这似乎有违“天底下没有免费的午餐”的道理。它真的有那么完美吗?很多人认为 Julia 运行速度很快,因为它是即时编译(JIT)型的(也就是说,每条语句都使用编译的函数来运行,这些函数要么在使用之前进行即时编译,要么在之前已经编译过并放在缓存中)。这就引出了一个问题:Julia 是否提供了比 Python 或 R 语言(MATLAB 默认使用 JIT)更好的 JIT 实现?因为人们在这些 JIT 编译器上所做的工作比 Julia 要多得多,所以我们凭什么认为 Julia 这么快就会超过这些编译器?但其实这完全是对 Julia 的误解。我想以一种非常直观的方式说明,Julia 的速度之所以快,是因为它的设计决策。Julia 的的核心设计决策是通过多重分派实现专门化的类型稳定性,编译器因此可以很容易地生成高效的代码,同时还能够保持代码的简洁,让它“看起来就像一门脚本语言”。但是,在本文的示例中,我们将看到 Julia 并不总是像其他脚本语言那样,我们必须接受
  • 干掉RESTful:GraphQL真香!
    REST作为一种现代网络应用非常流行的软件架构风格,自从Roy Fielding博士在2000年他的博士论文中提出来到现在已经有了20年的历史。它的简单易用性,可扩展性,伸缩性受到广大Web开发者的喜爱。REST 的 API 配合JSON格式的数据交换,使得前后端分离、数据交互变得非常容易,而且也已经成为了目前Web领域最受欢迎的软件架构设计模式。但随着REST API的流行和发展,它的缺点也暴露了出来:滥用REST接口,导致大量相似度很高(具有重复性)的API越来越冗余。对于前端而言:REST API粒度较粗,难以一次性符合前端的数据要求,前端需要分多次请求接口数据。增加了前端人员的工作量。对于后端而言:前端需要的数据往往在不同的地方具有相似性,但却又不同,比如针对同样的用户信息,有的地方只需要用户简要信息(比如头像、昵称),有些地方需要详细的信息,这就需要开发不同的接口来满足这些需求。当这样的相似但又不同的地方多的时候,就需要开发更多的接口来满足前端的需要。增加了后端开发人员的工作量和重复度。那我们来分析一下,当前端需求变化,涉及到改动旧需求时,会有以下这些情况:做加法:产品需求增加,页面需要增加功能,数据也就相应的要增加显示,那么REST接口也需要做增加,这种无可厚非。做减法:产品需求减少,页面需要减少功能,或者减少某些信息显示,那么数据就要做减法。一种通常懒惰的做法是
  • 什么是参照透明性?(What is referential transparency?)
    问题 参照透明性一词是什么意思? 我听说它被描述为“这意味着您可以用等于替换等于”,但这似乎是一个不足的解释。 回答1 术语“参照透明性”来自分析哲学,它是根据逻辑和数学方法分析自然语言构造,陈述和论点的哲学分支。 换句话说,它是计算机科学之外最接近我们所谓的编程语言语义学的学科。 哲学家威拉德·奎因(Willard Quine)负责提出参照透明性的概念,但在伯特兰·罗素(Bertrand Russell)和阿尔弗雷德·怀特黑德(Alfred Whitehead)的研究方法中也隐含了这一点。 从本质上讲,“参照透明”是一个非常简单而明确的想法。 在分析哲学中,术语“指代物”用于谈论表达式所指的东西。 它与我们在编程语言语义中所说的“含义”或“表示”大致相同。 以安德鲁·伯克特(Andrew Birkett)为例(博客文章),“苏格兰的首都”一词指的是爱丁堡市。 那是“指称”的简单例子。 如果用引用同一实体的另一个术语替换上下文中的一个词不会改变其含义,则该句子中的上下文是“相对透明的”。 例如 苏格兰议会在苏格兰首都举行会议。 的意思与 苏格兰议会在爱丁堡举行会议。 因此,“苏格兰议会在……开会”这一上下文是参照透明的上下文。 我们可以用“爱丁堡”代替“苏格兰的首都”,而无需改变含义。 换句话说,上下文仅关心该术语所指的内容,而无所谓。 这就是上下文“相对透明”的意义。 另一方面
  • 关键字列表有什么好处?(What is the benefit of Keyword Lists?)
    问题 在长生不老药中,我们有地图: > map = %{:a => "one", :b => "two"} # = %{a: "one", b: "two"} > map.a # = "one" > map[:a] # = "one" 我们还有关键字列表: > kl = [a: "one", b: "two"] # = [a: "one", b: "two"] > kl2 = [{:a, "one"},{:b, "two"}] # = [a: "one", b: "two"] > kl == kl2 # = true > kl[:a] # = "one" > kl.a # = ** (ArgumentError) 为何两者兼而有之? 句法? 是因为关键字列表具有更灵活的语法,允许将它们定义为没有卷曲,甚至没有括号作为函数调用的最后一个参数吗? 那为什么不给Maps这种语法糖呢? 重复的密钥? 是因为关键字列表可以有重复的关键字吗? 为什么要同时访问地图样式和重复键? 表现? 是因为关键字列表具有更好的性能? 那为什么要有地图呢? 并且,地图不应该比键元组列表在按键查找成员方面更有表现吗? JS Array和Ruby Hash的外观如何? 是吗 我了解从结构上讲它们是不同的数据表示形式。 在我看来,长生不老药中的关键字列表通过异常的语法(3种不同的语法变体)
  • 朱莉娅语言真的如它声称的那样快吗?(Is the Julia language really as fast as it claims?)
    问题 在这篇文章发表之后,我决定将Julia对照GNU Octave进行基准测试,结果与julialang.org中说明的加速不一致。 我用CXXFLAGS='-std=c++11 -O3'编译了Julia和GNU Octave,得到的结果是: GNU八度 a=0.9999; tic;y=a.^(1:10000);toc Elapsed time is 0.000159025 seconds. tic;y=a.^(1:10000);toc Elapsed time is 0.000162125 seconds. tic;y=a.^(1:10000);toc Elapsed time is 0.000159979 seconds. -- tic;y=cumprod(ones(1,10000)*a);toc Elapsed time is 0.000280142 seconds. tic;y=cumprod(ones(1,10000)*a);toc Elapsed time is 0.000280142 seconds. tic;y=cumprod(ones(1,10000)*a);toc Elapsed time is 0.000277996 seconds. 茱莉亚(Julia) tic();y=a.^(1:10000);toc() elapsed time: 0
  • 如何在julia中创建一个行为类似于标准Java类的“单个调度,面向对象的类”,其中包含公共/私有字段和方法(How to create a “single dispatch, object-oriented Class” in julia that behaves like a standard Java Class with public / private fields and methods)
    问题 我在一本书中读到“您无法使用obj.myfunc()之类的单派发式方法在julia中创建传统的“类””……我认为这听起来像是挑战,而不是事实。 因此,这是我的带有公共/私有字段和方法的JavaClass类型,仅出于在朱莉娅身上遇到类似丑陋事情的震惊和恐怖因素,毕竟开发人员已经避免了这种麻烦: type JavaClass # Public fields name::String # Public methods getName::Function setName::Function getX::Function getY::Function setX::Function setY::Function # Primary Constructor - "through Whom all things were made." function JavaClass(namearg::String, xarg::Int64, yarg::Int64) # Private fields - implemented as "closed" variables x = xarg y = yarg # Private methods used for "overloading" setY(yarg::Int64) = (y = yarg; return nothing) setY(yarg
  • 什么时候将一种语言视为脚本语言? [关闭](When is a language considered a scripting language? [closed])
    问题 关门了。 这个问题是基于意见的。 它当前不接受答案。 6年前关闭。 已锁定。 该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。 它目前不接受新的答案或互动。 是什么使语言成为脚本语言? 我听说有人说“当它被解释而不是编译时”。 这将使PHP(例如)成为脚本语言。 那是唯一的标准吗? 还是有其他标准? 也可以看看: “脚本”和“应用程序”有什么区别? 回答1 脚本语言是一种“脚本化”其他事情以完成工作的语言。 主要重点不是主要构建自己的应用程序,而是使现有应用程序按您想要的方式运行,例如,用于浏览器的JavaScript,用于MS Office的VBA。 回答2 简单的。 当我使用它时,它是一种现代的动态语言,当您使用它时,它只是一种脚本语言! 回答3 传统上,当谈论脚本与编程的区别时,将解释脚本并编译程序。 语言可以通过不同的方式执行-解释或编译(转换为字节码或机器码)。 这不会使一种或另一种语言成为可能。 在某些人眼中,语言的使用方式使其成为脚本语言(例如,主要使用C ++开发的游戏开发人员将在Lua中编写对象脚本)。 同样,线条也模糊了-一个人可以将一种语言用于编程,而另一个人可以将同一种语言用于脚本语言。 这是来自维基百科有关脚本语言的文章: 脚本语言,脚本语言或扩展语言是一种编程语言,可以控制一个或多个软件应用程序。 “脚本”与应用程序的核心代码不同
  • OOP的意义是什么?(What's the point of OOP?)
    问题 已锁定。 该问题及其答案被锁定,因为该问题是题外话,但具有历史意义。 它目前不接受新的答案或互动。 据我所知,尽管在OOP教育,语言和工具上花费了数百万或数十亿美元,但OOP并没有提高开发人员的生产力或软件可靠性,也没有降低开发成本。 很少有人严格地使用OOP(很少有人坚持或理解LSP等原则); 人们对问题域进行建模的方法似乎几乎没有统一性或一致性。 通常,该类仅用于其语法糖。 它将记录类型的函数放入它们自己的小命名空间中。 我已经为各种应用程序编写了大量代码。 尽管在某些场合中,真正的可替代子类型在应用程序中发挥了重要作用,但这些情况非常例外。 总的来说,尽管提供了大量的口头服务来谈论“重用”,但实际情况是,除非一段代码能够完全按照您的意愿去做,否则几乎没有成本效益的“重用”。 设计类以正确的方式进行扩展非常困难,因此扩展的成本通常很高,以至于“重用”根本就不值得。 在许多方面,这并不令我感到惊讶。 现实世界不是“ OO”,OO中隐含的想法(我们可以用某种分类法对事物建模)在我看来从根本上来说是有缺陷的(我可以坐在桌子,树桩,汽车引擎盖上) ,某人的膝盖-但其中之一不是-椅子)。 即使我们转向更抽象的领域,OO建模也常常是困难,违反直觉的,最终无济于事(请考虑圆形/椭圆形或正方形/矩形的经典示例)。 那我在这里想念什么? OOP的价值在哪里
  • 编程语言中的语法和语义之间有什么区别?(What is the difference between syntax and semantics in programming languages?)
    问题 编程语言(例如C,C ++)的语法和语义之间有什么区别? 回答1 语法与语言的结构或语法有关。 它回答了这个问题:我该如何构建一个有效的句子? 所有语言,甚至英语和其他人类(也称为“自然”)语言都具有语法,即定义句子是否正确构建的规则。 以下是一些C语言语法规则: 用分号分隔的语句将IF语句的条件表达式括在括号内通过将花括号括起来将多个语句组合为一个语句数据类型和变量必须在第一个可执行语句之前声明(此功能已在C99中删除。C99和后者允许混合类型声明。) 语义与句子的含义有关。 它回答了以下问题:这句话是否有效? 如果是这样,那句话是什么意思? 例如: x++; // increment foo(xyz, --b, &qrs); // call foo 在语法上是有效的C语句。 但是它们是什么意思呢? 尝试将这些语句转换为可执行的指令序列甚至有效吗? 这些问题是语义学的核心。 在第一条语句中考虑++运算符。 首先,尝试这样做是否有效? 如果x是float数据类型,则此语句没有任何意义(根据C语言规则),因此即使该语句在语法上是正确的,也将是一个错误。 如果x是指向某种数据类型的指针,则该语句的意思是“将sizeof(某种数据类型)添加到地址x的值并将结果存储到地址x的位置”。 如果x是标量,则该语句的含义是“在地址x的值上加一个并将结果存储到地址x的位置”。 最后,请注意
  • 在哪里可以找到语言和地区代码列表?(Where can I find a list of language + region codes?)
    问题 我用谷歌搜索(实际上是DuckDuckGo'ed),直到脸色发青,但在任何地方都找不到找到en-GB或fr-CA类型的语言代码的列表。 关于这些组件,有很多很好的资源,特别是W3C I18n页面,但是我希望有一个简单的字母列表,如果可能的话,也可以相当规范(像这样)。 找不到。 谁能指出我正确的方向? 非常感谢! 回答1 可以在Unicode的通用语言环境数据存储库中找到。 具体来说,此信息的JSON文件可在其cldr-json存储库中找到 回答2 有几种语言代码系统和几种区域代码系统,以及它们的组合。 当您指的是W3C页面时,我假设您指的是BCP 47中定义的系统。该系统在某种意义上是正交的,例如en-GB和fr-CA之类的代码仅将语言代码和区域代码结合在一起。 这意味着有很多可能的组合,其中大多数没有什么意义,例如ab-AX,这意味着阿布哈兹在奥兰语中说过(我认为,在理论上讲,阿布哈兹人在这里讲的都是阿布哈兹,尽管如此,但没有任何一个社区当然有可能)。 因此,任何语言区域组合列表都只是在某种意义上很重要的组合的实用列表,或者在某种意义上受到某些软件的支持。 您发现的规范定义了一般原则以及不同“子标签”(例如主要语言代码和地区代码)的权威来源。 对于最重要的部分,官方注册机构维护语言的三个字母和两个字母的ISO 639代码,ISO站点包含区域的两个字母的ISO 3166代码
  • AI-自然语言处理-词性标注、命名实体识别、句法分析和语义分析
    学习目标 • 了解自然语言处理基本知识 • 掌握循环神经网络算法 • 掌握自然语言处理关键技术 • 了解自然语言处理的应用 词性标注 定义 • 词性标注:为分词结果中的每个单词标注一个正确的词性的程序,也即确定每个词是名词、动词、形容词或者其他词性的过程。例如:迈向/v 充满/v 希望/n 的/uj 新/a 世纪/n。 • 词性:是词汇基本的语法属性。 • 目的:是很多NLP任务的预处理步骤,如句法分析、信息抽取,经过词性标注后的文本会带来很大的便利性,但也不是不可或缺的步骤。 • 方法:基于规则的方法、基于统计的方法、基于深度学习的方法。 • 在中文中,一个词的词性很多时候都不是固定的,一般表现为同音同形的词在不同场景下,其表示的语法截然不同,这就为词性标注带来了很大的困难。但是,大多数词语只有一个词性,或者出现频次最高的词性远远高于第二位的词性。据说单纯选取最高频词性,就能实现80%准确率的中文词性标注程序。 命名实体识别 定义 • 命名体识别(Named Entities Recognition, NER):又称作“专名识别”,是指识别文本中具有特定意义的实体,主要包括人名、地名、机构名、专有名词等。例如:冶金/n 工业部/n 洛阳/ns 耐火材料/l 研究院/n。 • 分类:NER研究的命名实体一般分为3大类(实体类、时间类和数字类)和7小类(人名、地名、组织机构名、时间