在ocaml toplevel(版本3.11.2),这个简单的表达式给了我一个错误:
# let a = [] in if null a then 0 else 1;;
Error: Unbound value null
Run Code Online (Sandbox Code Playgroud)
我刚开始从oreilly书中学习ocaml ,它似乎经常使用null作为关键字 - 例如,在页面32的顶部:
# let rec size a_list =
if null a_list then 0
else 1 + (size (List.tl a_list));;
Run Code Online (Sandbox Code Playgroud)
我很尴尬地在这里问一个明显的googleable问题.但经过大量的谷歌搜索,我空手而归.所以我对谷歌查询建议持开放态度,因为我是直截了当的答案.(谷歌尝试失败:[ocaml"错误:未绑定值null"] [ocaml null关键字] [ocaml changelog null] [ocaml change null]).
问题:一旦ocaml关键字为null,但不再是?或者我安装了ocaml错误或拼错了什么?
我当然可以在代码中用"[]"替换每次出现的"null",但我很惊讶,书中的代码的逐字副本给我这么早的错误.这本书是否充满了其他的陷阱?我相信它是用ocaml 2.04编写的; 那太旧了?我选择它是因为我喜欢TOC和在线免费提供.除了这个零错误(我还有更多的责任归咎于自己而不是作者),解释很好,我期待着混合功能和命令式风格的讨论(对我来说,思维扩展,作为某人只熟悉c/c ++).
新手问题.我正在阅读非常好的Ocaml ORA书.当我从Marshal的部分开始使用magic_copy示例时,我更接近浏览器而不是终端,所以我在ocsigen的浏览器中尝试了它,我很惊讶地得到了结果:
(* js_of_ocaml *)
# let ora_magic_copy a =
let s = Marshal.to_string a [Marshal.Closures] in
Marshal.from_string s 0;;
val ora_magic_copy : 'a -> 'b = <fun>
# (ora_magic_copy 2 : float) +. 3.1;;
- : float = 5.1
Run Code Online (Sandbox Code Playgroud)
检查ocaml 2(书写当前版本)和ocaml 3.12.1(由我的机器上安装的顶层和js_of_ocaml使用)之间是否有变化,我在我的机器上安装的普通顶层中尝试了相同的示例书中解释的结果是:由于类型系统检查Marshaled值而导致的段错误.
(* Linux toplevel *)
# (ora_magic_copy 3: float) +. 2.1;;
Segmentation fault (core dumped)
Run Code Online (Sandbox Code Playgroud)
我只是好奇:为什么?
我看到在三种情况下,Marshal.to_string给出了相同的字符串:linux编组一个int,js_of_ocaml编组和int,js_of_ocaml编组一个浮点数.奇怪的是linux toplevel marshalling float.
这是由于js_of_ocaml使用javascript的基本类型吗?或者只是......未定义的行为?
我们正在组建一个系统,通过模数转换器卡读取~32个电压信号,对它们进行一些初步处理,并将结果(仍然分成32个通道)作为UDP数据包传递给网络,在那里它们由另一台计算机拾取并以各种方式(a)显示,(b)进一步处理,(c)搜索改变采集系统状态的标准,或(d)AC的某种组合.同时,GUI进程正在计算机上运行,后者通过UDP打包的命令消息在后面的进程(vis计算机)上运行,这些进程在数据生成计算机和vis计算机的多个进程中改变状态.
我是网络编程的新手,我很难选择网络拓扑.对于相对较小的应用程序,是否有任何关于网络拓扑的启发式(或书籍章节,论文),而不是灵活地传递数据,命令和命令确认的需要?
系统细节:
原始数据采集发生在一个Linux机器上.简单地处理数据,保存到磁盘和推送到网络使用大约25%的CPU容量和少量内存.少于0.5 Mb /秒的数据传输到网络.所有用于数据生成的代码都是用c ++编写的.
另一台linux机器运行多个可视化/处理/ GUI流程.GUI控制采集机和vis /处理/ GUI计算机本身的处理.这段代码主要是用c ++编写的,Python中有一些小实用程序.
我们将编写其他想要监听原始数据,处理过的数据和传递的所有命令的应用程序; 那些应用程序也希望发出命令 - 我们无法预测我们想要编写多少这样的模块,但我们期望有3或4个数据繁重的进程将所有32个输入流转换为单个输出; 以及3或4个一次性小应用程序,如"命令记录器".模块化要求意味着我们希望旧的数据生成器和命令发布者不知道有多少监听器在那里.我们还希望收件人能够确认命令.
这两台机器通过交换机连接,数据包(数据和命令,以及确认)都以UDP格式发送.
我们想到的五种可能性:
数据流,命令和确认以端口号为目标.数据生成器将独立数据流作为UDP数据包发送到可视化计算机上由独立可视化工具进程绑定的不同端口号.每个进程还绑定一个侦听端口以接收传入命令,另一个端口用于传入确认传出命令.这个选项似乎很好,因为内核负责流量/过滤数据包; 但是很糟糕,因为在面对不可预测的附加模块时,很难看到进程如何相互对话; 它似乎也导致了绑定端口的爆炸.
数据流通过端口号定向到各自的可视化器,每个进程绑定一个端口以侦听命令.但是所有命令发布者都将其命令发送到数据包转发器进程,该进程知道所有进程的命令输入端口,并将每个命令转发给所有进程.确认也会发送到此通用命令输入端口并转发到所有进程.我们将有关每个命令的预期目标和每个确认的信息打包到命令/ ack数据包中,因此进程本身必须筛选所有命令/确认以查找与它们相关的命令/确认.
数据包转发器进程也是所有数据包的目标.所有数据包和所有命令包都被转发到40个不同的进程.这显然会给子网带来更多的流量; 它还可以清除绑定端口的爆炸.
两个分组分发器可以在vis计算机上运行 - 一个向所有端口广播命令/ ack.另一个只将数据广播到可能需要数据的端口.
我们的32个可视化流程可以捆绑到一个流程中,该流程可以为32个信号绘制数据,从而大大减少了选项3导致的额外流量.
如果你已经尝试过在少数机器上的多个进程之间传递数据,并且有一些关于哪些策略是健壮的智慧或经验法则,我将非常感谢你的建议!(欢迎在图片中澄清要求)