为什么不';我们不能用LISP语法编写haskell吗?(我们可以!)

为什么不';我们不能用LISP语法编写haskell吗?(我们可以!),haskell,macros,lisp,defmacro,Haskell,Macros,Lisp,Defmacro,它。。。有点像你们(这绝对是编译的,改编自): main::IO() main=(do) (putStrLn“启动服务器…”) (斯科特3000(do (获取“/hello/:name” (文本(“你好”(参数“名称”)“!”) (获取“/用户” (用户) (获取“/users/:id” (json(过滤器(matchesId(参数“id”))allUsers‘‘‘‘‘‘‘‘) (我知道的哈斯克尔不足以把转换成简单的帕伦,但聪明人很容易做到。) 我们为什么要这样做?我们可以用任何lisp宏引擎

它。。。有点像你们(这绝对是编译的,改编自):

main::IO()
main=(do)
(putStrLn“启动服务器…”)
(斯科特3000(do
(获取“/hello/:name”
(文本(“你好”(参数“名称”)“!”)
(获取“/用户”
(用户)
(获取“/users/:id”
(json(过滤器(matchesId(参数“id”))allUsers‘‘‘‘‘‘‘‘)
(我知道的哈斯克尔不足以把
转换成简单的帕伦,但聪明人很容易做到。)

我们为什么要这样做?我们可以用任何lisp宏引擎预处理Haskell!微不足道的

想象一下。HASKELL和LISP在一起。我们可以统治银河系

(我知道你的想法,但我实际上已经仔细考虑过了:在这个例子中,维德是Lisp,卢克是Haskell,尤达是Alonzo Church)

(编辑:“谢谢所有回答和评论的人,我现在聪明多了。 我认为这项技术的最大问题还没有提到,一位朋友IRL指出:如果你编写了一些lispy预处理器,你的IDE和工具就会失去类型检查、语法突出显示和理解能力。这听起来像是我的一个难题。”

“我现在正在关注这个项目,这是我想要的lisp风格的haskell项目!”

haskell的语法来自于,一种出现在lisp之后不久的语言,Peter J.Landin在1966年的文章中对此进行了描述

第6节专门讨论与LISP的关系:

ISWIM可以被看作是从它的 同名的承诺名单,其声誉的手到嘴 存储分配,它的教学方法依赖于硬件, 厚重的支架,与传统的妥协

同一节后面部分:

ISWIM的文本外观与LISP的s表达式不同它 更接近LISP的M表达式(构成非正式的 在手工编写LISP时用作中间结果的语言 程序)。ISWIM具有以下附加功能:[……]

因此,有明确的意图是偏离LISP语法,或者至少偏离S表达式

  • Haskell没有s-exp,因此括号仅用于标记归约和构造元组的优先级,这也意味着在Haskell中使用类似lisp的宏并不容易,因为它们大量使用s-exp和动态类型
  • Haskell有一个右关联函数应用程序(即($),它涵盖了括号的大多数用例
  • 空格在Haskell中有语义意义,这就是我们大多数人写作的原因
  • 而不是

    do { p1
       ; p2
       ; p3
       }
    

    在结构上,Haskell程序由一组模块组成。每个模块由一组声明组成。模块和声明是惰性的——它们的存在本身不会导致任何事情发生。它们只是在静态名称空间中形成条目,编译器在生成代码时使用该名称空间解析名称

    顺便说一下,你可能会在这里对
    Main.Main
    吹毛求疵。作为入口点,运行它只是为了定义。这很公平。但是,只有当
    Main.Main
    需要时,才在代码生成中使用其他每个声明,而不仅仅是因为它存在

    相比之下,Lisp是更具动态性的系统。Lisp程序由按顺序执行的一系列s表达式组成。每一个都会导致代码执行产生任意副作用,包括修改全局名称空间


    这里的事情得到了更多的意见为基础。我认为Lisp的动态结构与其语法的规律性密切相关。语法检查无法区分用于向全局命名空间添加值的s表达式和用于运行其副作用的s表达式。如果没有句法上的区别,添加语义上的区别似乎非常尴尬。所以我认为Lisp语法过于规则,无法用于Haskell中不同类型代码之间有严格语义分离的语言。相比之下,Haskell的语法提供了与语义区别相匹配的语法区别。

    因为Lisp使用了太多的括号,使其非常不可读。/rant(1)所有语言都可以用Lisp符号表示,但人们的品味不同。就我个人而言,我觉得Haskell是不可读的,我非常喜欢单词而不是Perlism,我也不喜欢记住哪个操作符优先于其他操作符,但这不是Haskell喜欢的(参见箭头语法、组合符等)。从视觉上讲,我更希望Haskell使用完整的Unicode并使用现有的数学运算符,比如APL。(2) 在我看来,Haskell用户似乎不太重视元编程。下面是一个在Racket中编写类似Haskell语言的实验:我不确定它是否真的能给你带来很多好处。您的宏仍然需要了解所有特殊的语法形式--您不希望对作为模式的语法位和作为表达式的语法位运行相同的递归操作,例如,因此,你不能只编写一个宏,它在经过转换的
    let
    表达式的位上统一工作——因此对文本的统一序列化实际上没有帮助;尝试添加一个新功能成为了一种冒险,它试图尽可能地重用现有的关键字(以避免破坏假定某个单词可用作标识符的代码),而这种方式不会对现有的关键字使用产生歧义。符号有其位置;无论是使用不足还是过度使用它们都不是正确的答案。太棒了!然而,正如在我的例子中一样,兼容性似乎仍然存在?@0atman您可以编写一个括号内的Haskell(我通常更喜欢使用显式括号而不是
    $
    运算符),但这种相似性有点欺骗性,
    do { p1
       ; p2
       ; p3
       }