通常与函数式语言相关的哪些技术或范例也可以在命令式语言中有效地使用?
例如:
我碰巧真的不想担心功能语言中的状态.如果我特别顽固,我可能会编写C程序而不修改变量,只将我的状态封装在传递给函数的变量和函数返回的值中.
即使函数不是第一类值,我也可以在Java中用一个对象包装一个,并将其传递给另一个方法.像功能编程一样,只是不那么有趣.
那么,对于函数式编程的资深人士来说,当您使用命令式语言进行编程时,FP的哪些想法已成功应用?
在clojure中,如何键入类型提示我创建的类型?(我想嵌套类型.)
我以为这会起作用:
(deftype A
[#^somePrimitive someField])
(deftype B
[#^A Avalue])
Run Code Online (Sandbox Code Playgroud)
这会显示一条错误消息:
Unknown location:
error: java.lang.ClassNotFoundException: A
Run Code Online (Sandbox Code Playgroud)
注意:clojure类型是一个新功能,目前只存在于clojure的"new"分支中.
编辑:我对java和clojure类型的clojure类型提示的不同方式感到困惑.java类被暗示为
#^java.some.class
Run Code Online (Sandbox Code Playgroud)
而clojure类型暗示为:
#^:some.Namespace/type
Run Code Online (Sandbox Code Playgroud) 可以任意扩展Clojure结构,添加新字段.
是否可以以类似的方式扩展类型(使用deftype创建)?
编辑:对于未来访客的好处,正如布莱恩在下面指出的,这个功能可能会有所变化.
我正在尝试使用deftype(来自流行的clojure 1.2分支)来创建一个实现java Servlet接口的java类.我希望下面的代码能够编译(即使它不是很有用).
(ns foo [:import [javax.servlet Servlet ServletRequest ServletResponse]])
(deftype servlet []
javax.servlet.Servlet
(service [this
#^javax.servlet.ServletRequest request
#^javax.servlet.ServletResponse response]
nil))
Run Code Online (Sandbox Code Playgroud)
但它没有编译.编译器生成消息:
Mismatched return type: service, expected: void, had: java.lang.Object
[Thrown class java.lang.IllegalArgumentException]
Run Code Online (Sandbox Code Playgroud)
这对我来说没有意义,因为我回来了.因此,方法的返回类型无效的事实应该不是问题.例如,对于java.util.Set接口:
(deftype bar [#^Number n] java.util.Set (clear [this] nil))
Run Code Online (Sandbox Code Playgroud)
编译没有问题.
那么我对Servlet接口做错了什么?
要明确:我知道典型的情况是将一个servlet抽象类子类化,而不是直接实现这个接口,但是仍然可以这样做.
堆栈跟踪:
(deftype servlet ...的堆栈跟踪是:
Mismatched return type: service, expected: void, had: java.lang.Object
[Thrown class java.lang.IllegalArgumentException]
Restarts:
0: [ABORT] Return to SLIME's top level.
Backtrace:
0: clojure.lang.Compiler$NewInstanceMethod.parse(Compiler.java:6461)
1: clojure.lang.Compiler$NewInstanceExpr.build(Compiler.java:6119)
2: clojure.lang.Compiler$NewInstanceExpr$DeftypeParser.parse(Compiler.java:6003)
3: clojure.lang.Compiler.analyzeSeq(Compiler.java:5289)
4: clojure.lang.Compiler.analyze(Compiler.java:5110)
5: …Run Code Online (Sandbox Code Playgroud) 这可能是一个愚蠢的问题,但是:
假设一个表达式仅依赖于文字,或者仅依赖于文字的其他表达式; 编译器会在编译时对此进行评估吗?
假设我有,
(def a (some-time-consuming-function some-literal))
(def b (some-other-time-consuming-function a))
Run Code Online (Sandbox Code Playgroud)
是否会在编译时完全评估b和a,以便用户不受影响?
编辑:非常感谢,所有的答案都非常有帮助.
编辑6.6.2011: 事实证明,如果您尝试使用此技术预先计算非常大的数据结构,则很容易使类文件太大而无法加载.在这些情况下,您希望创建一个将被读入的文件而不是将要加载的类文件.这些答案中描述的宏观技巧只应在返回值不是过大的结构的情况下应用.
抛出的错误是:"java.lang.ClassFormatError:此类索引无效"有关相关情况的讨论,请参阅此主题.
我正在尝试在64位mac上编译svdlibc.运行make文件将返回错误消息:
main.c:1: error: CPU you selected does not support x86-64 instruction set
main.c:1: error: CPU you selected does not support x86-64 instruction set
make: *** [main.o] Error 1
Run Code Online (Sandbox Code Playgroud)
哪个没有多大意义.
make文件是:
# Linux or Windows:
CC = gcc -Wall -O4 -march=i486
# CC = icc -w1 -O3 -march=i486
# Macintosh:
ifeq ($(HOSTTYPE),powerpc)
CC = cc -pipe -O3 -Wall -fno-common -arch ppc
endif
LIBS=-lm
OBJ=svdlib.o svdutil.o las2.o
svd: Makefile main.o libsvd.a
${CC} ${CFLAGS} -o svd main.o libsvd.a ${LIBS}
mv -f …Run Code Online (Sandbox Code Playgroud) 有没有一种方便的方法来使用Scala的解析器组合器来解析缩进很重要的语言?(例如Python)
假设我想将一个复杂的数据结构(例如树)存储到磁盘上.连接我的数据结构中的节点的内部指针是指针,但我不能只将这些指针写入磁盘,因为当我读回数据结构时,内存位置将会发生变化.
那么将指针存储在磁盘上的正确方法是什么?答案就像(文件,偏移)一样简单,还是有些东西我不知道?我可以直观地指出如何将指针转换为(文件,偏移)对,然后再返回,但是我应该注意一些细微之处吗?
编辑:我应该提一下,我特别感兴趣的是数据库如何在内部执行此操作,对于b树.虽然我很欣赏基于XML的答案,但我可能会提出比我应该更普遍的问题.
在Haskell和OCaml中,都可以从C程序调用语言.为广泛使用这种技术的Windows,Mac或Linux创建Native应用程序有多可行?
(我知道有像wxHaskell这样的GUI库,但是假设有人希望只用外语获得一部分应用程序逻辑.)
或者这是一个可怕的想法?
哪个是更好的惯用语法练习,用于表示由不同节点类型组成的树:
A.使用deftype或defrecord定义几种不同类型记录中的树构建:
(defrecord node_a [left right])
(defrecord node_b [left right])
(defrecord leaf [])
(def my-tree (node_a. (node_b. (leaf.) (leaf.)) (leaf.)))
Run Code Online (Sandbox Code Playgroud)
B.用向量构建树,用关键字指定类型:
(def my-tree [:node-a [:node-b :leaf :leaf] :leaf])
Run Code Online (Sandbox Code Playgroud)
我看到的大多数clojure代码似乎都支持使用通用数据结构(向量,映射等),而不是数据类型或记录.Hiccup,举一个例子,非常好地使用vector + keyword方法表示html.
什么时候我们应该比另一种更喜欢一种风格?