Functional programming Racket中的define struct是什么?为什么没有变量?

Functional programming Racket中的define struct是什么?为什么没有变量?,functional-programming,scheme,racket,Functional Programming,Scheme,Racket,在我大学的一门CS课程中,我们必须与Racket合作。我大学前的大部分编程时间都是用PHP、Java和JavaScript编写的。我知道Racket是一种函数式编程语言,就像JavaScript一样(编辑:当然不是。但我觉得我在用它进行“函数式”编程,在看到答案后,这是一种错误的认识。)但我仍然不理解Racket(Scheme)的一些基本特征 为什么没有“真实”变量?为什么所有东西都是Racket/Scheme中的函数?为什么语言设计者不包括它们 什么是定义结构?它是一个函数吗?这是一节课吗?不

在我大学的一门CS课程中,我们必须与Racket合作。我大学前的大部分编程时间都是用PHP、Java和JavaScript编写的。我知道Racket是一种函数式编程语言,就像JavaScript一样(编辑:当然不是。但我觉得我在用它进行“函数式”编程,在看到答案后,这是一种错误的认识。)但我仍然不理解Racket(Scheme)的一些基本特征

  • 为什么没有“真实”变量?为什么所有东西都是Racket/Scheme中的函数?为什么语言设计者不包括它们

  • 什么是定义结构?它是一个函数吗?这是一节课吗?不知何故,由于我的PHP背景,我总是认为它是一个类,但这并不是真的正确

  • 我的问题是我想理解语言的概念。我个人仍然认为它很奇怪,与我以前使用的任何东西都不一样,所以我的大脑试图将它与JavaScript进行比较,但对我来说它似乎太不一样了。与JavaScript的相似之处/不同之处会有很大帮助

  • 方案中有变量

    > (define a 1)
    #<unspecified>
    > a
    1
    > (set! a 2)
    #<unspecified>
    > a
    2
    
    >(定义1)
    #
    >a
    1.
    >(集!a 2)
    #
    >a
    2.
    
    这种语言中甚至有可变的数据结构

    > (begin
    >   (define v (make-vector 4))
    >   (vector-set! v 0 'foo)
    >   (vector-set! v 1 'bar)
    >   (vector-set! v 2 'baz)
    >   (vector-set! v 3 'quux))
    #<unspecified>
    > v
    #(foo bar baz quux)
    
    >(开始
    >(定义v(生成向量4))
    >(向量集!v0'foo)
    >(向量集!v 1'巴)
    >(向量集!v2'baz)
    >(向量集!v3'qux))
    #
    >五
    #(富吧巴兹库克斯)
    
    Scheme不是一种纯粹的FP语言;它允许命令式编程,尽管它主要面向函数式编程。这是方案的发明者做出的设计选择

  • define struct
    是一种特殊形式;它的语法,如JavaScript中的
    函数
    返回
    关键字

  • Scheme非常具有“真实”变量

    函数式语言(如Racket)和命令式语言(如JavaScript或PHP)的区别在于,在函数式语言中,通常不使用可变状态。变量最好被认为是值的名称,而不是可以保存值的容器。您没有使用循环构造之类的方法来更改变量中的值,而是使用递归进行流控制

    define struct
    是一种特殊的语法形式,类似于其他语言中的关键字。(与其他语言不同,在Scheme中,您可以创建自己的语法形式。)它定义了一个结构类型,类似于类,但没有方法。它还定义了许多函数,帮助您利用新的结构类型

  • 球拍中有“真实”变量。例如,如果你写这个 代码

    “全局”变量
    x
    将设置为值3。如果你现在写信

    (set! x 4)
    
    变量
    x
    将其值更改为4。所以,在球拍中你可以 有一个像任何“正常”语言一样的“正常”变量,如果你 希望事实上,在Racket中,首选的编程风格是 功能性的而不是程序性的。函数式编程风格 不鼓励变异

  • define struct
    是用于定义“结构”的球拍宏 “模板”以及其他一些东西。例如,如果你 写:

    您刚刚定义了一个“结构模板”(即名为
    coord的用户类型)
    有两个“插槽”:
    x
    y)
    。之后,您现在可以:

    • 创建结构的新“实例”
      coord
      ,例如:
      (合作2 3)

    • 从结构对象中提取插槽值:

      (coord-x (make-coord 2 3)) ;will return 2
      

    • 你可以问,某个给定的对象是否就是那个结构。对于 例如,
      (coord?3)
      将返回
      #f
      ,因为3不是
      coord
      结构,但是

      (coord? (make-coord 2 3)) ;will return #t
      

  • 也许最流行的或流行的编程方法(使用C++语言、JavaScript和java语言)有一些特点。你可能会想当然地认为这是不言而喻的,唯一可能的方法。这些措施包括:

    • 命令
    你专注于说“做这一步,然后下一步”等等

    • 使用突变
    您声明了一个变量,并不断为其分配不同的值(“修改它”)

    • 面向对象
    将代码和数据捆绑到类中,并将它们的实例声明为对象。然后对对象进行变异

    学习计划或球拍会帮助你明白,这些并不是唯一的方法

    一开始它可能会让你的大脑受伤,就像哲学课可能会让你质疑你认为理所当然的事情一样。然而,与哲学课不同的是,让大脑受伤会有一些实际的回报

    另一种选择:

    • 功能性的(而不是命令性的)。关注返回值的表达式,而不是创建步骤的待办事项列表
    • 不变的。同上
    • 不是面向对象的。使用类的对象可以很好地解决一些问题,但不是所有问题。如果您想将代码与数据捆绑在一起,有一些更通用的方法,例如使用“let over lambda”的闭包等等。有时,您不需要所有类的“包袱”,尤其是继承

    计划和球拍使探索这些想法变得容易。但是它们不像Haskell那样是“纯功能性的”,所以如果你真的想做命令式的、可变的、面向对象的事情,你也可以这样做。然而,学习Racket以与Javascript相同的方式做事情没有多大意义。

    Javascript不是函数式编程语言。是的,你是对的。但我经常觉得我用它做的很多事情都是函数式编程。但是考虑到我在这里学到的东西,它更多的是用函数进行程序化编程。或者你会说哪种编程风格最适合WebJavaScri
    (coord-x (make-coord 2 3)) ;will return 2
    
    (coord-y (make-coord 2 3)) ;will return 3
    
    (coord? (make-coord 2 3)) ;will return #t