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

wow*_*ick 5 scheme functional-programming racket

在我在大学的一门CS课程中,我们必须与Racket合作.我在大学之前的大部分编程时间都花在了PHP和Java以及JavaScript上.我知道球拍是一个函数式编程语言,就像JavaScript的(编辑:当然,这不是,但我觉得我做的"功能"的编程与它,这眼看着答案后,是一种错误的认识.)但是我仍然不了解Racket(Scheme)的一些基本特征.

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

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

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

Rac*_*oob 20

  1. Racket中有"真正的"变量.例如,如果您编写此代码

    (define x 3)
    
    Run Code Online (Sandbox Code Playgroud)

    'global'变量x将设置为值3.如果你现在写

    (set! x 4)
    
    Run Code Online (Sandbox Code Playgroud)

    变量x会将其值更改为4.因此,在Racket中,如果需要,您可以使用任何"普通"语言中的"正常"变量.事实上,在Racket中,首选的编程风格是功能性的而不是程序性的.在函数式编程风格中,不鼓励变量变异.

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

    (define-struct coord (x y))
    
    Run Code Online (Sandbox Code Playgroud)

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


Gre*_*ott 7

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

  • 势在必行

你专注于说"做这一步,然后下一步"等等.

  • 使用变异.

您声明一个变量,并继续为其分配不同的值("mutate it").

  • 面向对象.

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

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

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

替代:

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

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


Tay*_*mon 5

Scheme非常具有"真实"变量.

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

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