什么是Racket中的define-struct,为什么没有变量?

时间:2012-04-10 11:43:00

标签: functional-programming scheme racket

在我的大学CS课程中,我们必须与Racket合作。我在大学之前的大部分编程时间都花在了PHP和Java以及JavaScript上。我知道Racket是一种函数式编程语言,就像JavaScript一样(编辑:当然不是。但我觉得我正在用它进行'功能'编程,在看到答案之后,这是一种错误的看法。)但我仍然不了解Racket(Scheme)的一些基本特征。

  1. 为什么没有“真正的”变量?为什么一切都在Racket / Scheme中起作用?为什么语言设计师不包括它们?

  2. 什么是define-struct?这是一个功能吗?这是一堂课吗?我不知何故,因为我的PHP背景,总是认为它是一个类,但这可能不是真的正确。

  3. 我的问题是我想要理解语言的概念。我 personaly 仍然认为它真的很奇怪而且不像我之前使用的任何东西,所以我的大脑试图将它与JavaScript进行比较,但它对我来说似乎有点不同。 Parales /与JavaScript的差异会有很大帮助!

4 个答案:

答案 0 :(得分:19)

  1. Racket中有'真实'变量。例如,如果你写这个 代码

    (define x 3)
    

    '全局'变量x将设置为值3.如果您现在写

    (set! x 4)
    

    变量x会将其值更改为4.因此,在Racket中您可以 如果你有一个'正常'变量,就像任何'正常'语言一样 想。事实上,在Racket中,首选的编程风格是 功能性而非程序性。在函数式编程风格 不鼓励变异。

  2. define-struct是一个Racket宏,用于定义'结构 模板'以及其他一些东西。例如,如果你 写:

    (define-struct coord (x y))
    

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

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

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

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

      (coord-y (make-coord 2 3)) ;will return 3
      
    • 你可以问一些给定的对象是否只是那个结构。对于 例如,(coord? 3)将返回#f,因为3不是coord类型 结构,但

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

答案 1 :(得分:7)

也许最流行或最流行的编程方式(使用C ++,Javascript和Java等语言)具有一些特征。您可以将它们视为理所当然,这是唯一可行的方式。它们包括:

  • 势在必行

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

  • 使用变异。

您声明一个变量,并继续为其指定不同的值(“mutate it”)。

  • 面向对象的。

将代码和数据捆绑到类中,并将它们的实例声明为对象。然后你改变对象。

学习计划或球拍将帮助您了解这些不是解决问题的唯一方法。

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

替代方案:

  • 功能性(而非命令性)。专注于返回值的表达式,而不是制作待办事项列表。
  • 不可变。同上。
  • 不面向对象。使用类的对象可能是解决某些问题的好方法,但不是全部。如果要将代码与数据捆绑在一起,可以采用一些更通用的方法,例如使用“let over lambda”等封闭。有时你不需要所有课程的“包袱”,特别是继承。

Scheme和Racket让您可以轻松探索这些想法。但它们并不像Haskell那样“纯粹的功能”,所以如果你真的想做必要的,可变的,面向对象的事情,你也可以这样做。然而,学习Racket以与Javascript相同的方式做事并没有什么意义。

答案 2 :(得分:5)

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

功能语言(如Racket)和命令式语言(如JavaScript或PHP)之间的区别在于,在函数式语言中,您通常不使用可变状态。变量最好被认为是值的名称,而不是容纳值的容器。而不是使用循环结构之类的东西来改变变量中的值,而是使用递归进行流控制。

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

答案 3 :(得分:2)

  1. Scheme中有变量。

    > (define a 1)
    #<unspecified>
    > a
    1
    > (set! a 2)
    #<unspecified>
    > 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)
    

    Scheme不是纯粹的FP语言;它确实允许命令式编程,尽管它主要面向函数式编程。这是Scheme的发明者做出的设计选择。

  2. define-struct特殊表单;它的语法,如JavaScript中的functionreturn关键字。