F是纯功能连词。 最初设计为假的延伸的语言。F包含K3和DIP合并器的列表操作 乔伊的名字。支持浮点和符号数据类型。一次性分配 是在语法中强制执行的。概述了函数价电荷理论。F还包含一个一般的延续 原语$,以及XY的模式子语言。G是F的变体,其中K3副词被实现为原语。
这种语言是串联的。F个代币是单词, 单词表示功能,单词的拼接表示 函数的组合。在古典连词中 语言,从堆栈到堆栈,一切都是一个函数。在F中, 一切都是从三元数开始的函数 (环境;堆栈;队列)到三倍 (环境;堆栈;队列)。
这种语言纯粹是功能性的。没有 副作用。F有赋值,但没有重新赋值。这意味着 您不能使用变量来存储动态状态。F 赋值将名称与环境中的值相关联,该环境 作为参数传递并作为值返回。F也有 用于与运行时环境交互的命令和 文件系统,但这些操作在符号上是不同的 来自F:";h&34;、";r&34;、&;c. 它们仅用作调试辅助工具。
实现了所有的K个动词。一些K动词是 实现为基元,有些是在F前奏曲中派生的。 例如,K的原子原语@定义为 [#int~];即形状与空整数向量匹配。其中K 提供一对函数,其中一个很容易在 对于另一种情况,F将其中一个实现为基元,并派生 其他的。例如,AND是基元(&;)和或 都是派生出来的。划分相关对的标准很简单 这一点:派生的定义不能是非常低效的 与原始人相比,它取代了原始人。
所有基元都由单个符号表示。 虽然支持列表表示法([x y z]),但任何列表都可以 在功能上由';(引号)和,(联接)构成。
原始符号尽可能好记。那里 函数到符号的映射有五种方式 助记符:
符号被映射到K中的该函数(例如? Find)或FALSE(例如!用于报价)。
符号的名称是映射的 函数(例如';用于报价)
一对相关函数(倒数、或 近逆)映射到一对相关的 符号(例如/和\表示接受和丢弃)。
在将几个K个基元映射到一个码元的情况下, 基元应该形成一个容易记忆的组 基于某些共同属性;例如,两者都升级 和枚举返回索引,这些索引基于 升序关系,因此两者都映射到<;。
解释器的初始状态由一个 环境中含有F字的序曲,一句空话 结果堆栈和要计算的字符串(字符向量)。 对输入字符串进行标记化和解析,以获得初始 排队。
输入队列是K列表,可能包含整数, 浮点数、符号、NULL、函数和列表 (";引语";)。结果堆栈最初为空。 环境是一本K字典。F处理环境, 堆栈,并重复排队,直到队列为空。
如果队列中的第一项是整数、浮点数、NULL 原型符号`或列表,则将该项推送到 堆叠。
如果第一个项目是未定义的符号,那么如果它是一个洗牌 它已应用;否则,将(在环境中)创建一个变量 将堆栈的顶部作为值。
如果第一项是定义的符号,则其值为 (从环境中)检索并推送到堆栈上。
如果第一项是函数,则将其应用于 环境、堆栈和队列以产生新环境, 堆栈和队列。
注意到结果堆栈的域是一个适当的子集 输入队列域的。在排队的时候我们可能会发现 字符原子(如";r&34;)和字符串(如 胡言乱语。但是,当字符原子被执行时,它们就会被执行 都会求值,并且没有F基元会生成一个,并且字符串 是不处理的注释。
Trace命令显示以下项的堆栈和队列 跟踪列表T中的选定对象:
F>;[fac]";t"; F>;3面! 3♦Face! 3 2♦面!* 3 2 1♦面!** 6个 F>; F>;[fac cond]";t"; F>;3面! 3♦Face! 3[1=][][重复!普雷德!FAC!*]♦Cond! 3 2♦面!* 3 2[1=][][重复!普雷德!FAC!*]♦Cond!* 3 2 1♦面!** 3 2 1[1=][][重复!普雷德!Fac!*]♦条件!** 6个 F>; F>;[];t"; F>;3面! 6个。
09*-INT 123->;123 09*.09*-浮动123.45->;123.45 Az.AZ*name myName->;值或空 AZ*-AZ*洗牌10 20 ab-ba->;20 10 [..]列表[10+[3 a]]->;[10+[3 a]] +添加1 2+->;3 -SUB 2 3-->;1 *3 4*->;12 %div 5.3%->;1.666667 ^幂2 3^->;8个 _3.2层_->;3 =等于2 2=->;1 >;更多4 6>;->;0 &;和/min 4 3&;->;3 ~Match[1 2][1 2]~->;1 #Shape[1 2 3]#->;[3] |反转[1 2 3]|->;[3 2 1] @WHERE[0 1 1 0 1]@->;[1 2 4] @Flip[[1 2 3][4 5 6]]@->;[[1 4][2 5][3 6]] /Take 2[1 2 3]/->;[1 2] /RESHAPE[3 2][1 2 3]/->;[[1 2][3 1][2 3]] \DROP 2[1 2 3]\->;[3] \Cut[0 2][1 2 3]\->;[[1 2][3]] \Rotate[1 2 3 4]2\->;[3 4 1 2] ?找到[10 20 30]20?->;1 ?模数2[3 4 5]?->;[1 0 1] ;唯一[10 20 10 10 30];->;[10 20 30] :Group[10 20 10 10 30]:->;[[0 2 3][1][4]] <;枚举3<;->;[0 1 2] <;升级[10 30 20]<;->;[0 2 1] 。下部1 2[[2 3+]]。3 4->;1 2[5]3 4 。索引[[1 2 3][[1 0]。->;[2 1] 。Monad[[1 2 3][[1 0]][-1*]]。->;[-1-2 3] 。DYAD[[1 2 3][[1 0]]+[3 8]]。->;[9 53] 好了!无引号2[3+]!->;5 `DIP 2 3 4[+]`->;5 4 ';报价';+->;[+] ,JOIN[1][2 3],->;[1 2 3] $STATE%1 2 3';\$4 5 6->;4 5 6 1 2 3 )s->;的堆栈-&>堆栈模式 (S-&>;Q堆栈->;队列模式 }Q->;的队列-&>堆栈模式 {Q-&>;Q队列->;队列模式。
类型(4::) 对数表达式abs sqr sqrt楼层点多个inv LSq 在丹新堂有一件事,就是一件事,一件事。 画 在林彬的dv dvl di vs sv中。
NaN分钟(0n) 信息最大值(0i) 南南(0n) 无限大(0i) NULL NULL(_N) Sym原型sym(`) 整数空整数向量(!0) 浮点空的浮点向量(0#0.) Syms空sym向量(0#`)。
";..";注释1";跳过";2注释未处理 ";b";中断';x";b";信号错误(';x) 清除1 2;c#34;c#34;3 4清除,加载f,序曲 ";d";定义了';foo";d";是否定义了foo? ";e";错误0";e";设置/取消设置错误陷阱(\e) ";f";2个单元!设置F语义,清除 ";j";Joy";j";2单元集Joy语义,清晰 ";k";k 1 2";k";3 4出口到K ";l";加载';x";l";加载f/x.f|x.j ";m";测量[10<;]";m&34;测量时间(毫秒) ";o";word';map";o";显示单词形式 ";p";精度3";p";打印精度(\p) ";r";读取1 2";r";3 4读取、解析、求值 ";s";存储y';x";商店f/x.f|x.j ";t";跟踪空";t";3 4设置跟踪列表(T) ";u";取消定义x";u";取消定义x中的变量 ";v";变量1 2";v";3 4显示变量(!Environment) ";x";出口1 2";x";3 4_出口0 ";w";写入1 2";w";3 4格式,写入 ";z";停止1 2";z";3 4:继续。
空格(空格、制表符、回车)是 有必要把名字和名字分开,把数字和数字分开, 但不是数字中的名字。
名称必须以字母开头,并且可以包含字母、.、 或者是一张单人票。包含-的名称是洗牌符号。
数字表达式必须以数字或-开头 后跟数字,并且必须以数字结尾。一个浮点数 数值表达式必须正好包含一个。哪一个 两侧必须有数字。
整型枚举(&L;E) ~ATOM<;升级<;x 原子现时值(<;nonce) INT/INTS@WHERE&;x 列表@翻转+x 随机数 原子y?Mod y!x ~原子y?查找x?y 列出ATOM\旋转y!x 原子列表\Drop x_y 原子\滴x_(),y 列表列表\剪切x_y 1=#x。下文 X。指数/一元/二元。X。
错误的组合子如果和WHILE已经被 已消除,以及条件、如果和同时 都被定义为序曲中的词语。F的真值 比K更一般:0为FALSE,任何其他 值为真。
使用指定的名称(变量)会将指定的值 对堆栈上的它执行以下操作:
无引号的合并者!是乔伊的我!vbl.采取 堆栈上的顶部项x,并将 X到队列:
DIP组合器的定义与其在Joy中的定义相同。#^LAu#^LAu 获取堆栈上最上面的两个项目x,y,并 在队列前面加上y,,x。例如,在启用跟踪的情况下, 输入队列显示在菱形的右侧, 左侧的结果堆栈:
F>;10 2 3 4 20[+*]` ♦10 2 3 4 20[+*]` 10♦2 3 4 20[+*]` 10 2♦3 4 20[+*]` 10 2 3♦4 20[+*]` 10 2 3 4♦20[+*]` 10 2 3 4 20♦[+*]` 10 2 3 4 20[+*]♦` 10 2 3 4♦+*20 10 2 7♦*20 10 14♦20 10 14 20♦ F>;
堆栈将堆栈推送到堆栈上 取消堆栈将堆栈设置到堆栈的顶部 队列将堆栈顶部移动到队列 退出队列将队列末尾移动到堆栈。
$期望堆栈顶部有一个程序。该计划预计 它下面有两个引语:当前队列和它下面的 当前堆栈。F期望程序返回两个 报价:新队列,其下是新列表。
F>;12个缺点! [1 2] F>; F>;[1 2]uncons! 1[2] F>; F>;[1]uncons! 1个整数 F>; F>;[]uncons! 空[] F>; F>;2个无名氏! 2个整数。
F堆栈堆栈价大于堆栈大小。 F队列队列价数大于队列大小。 F模式堆栈大小大于模式方案大小。 F字符:<;x>;x是非法字符。 F现时值:<;x>;没有为提供的参数定义基元x。
J0(F语义)1(Joy语义)。 O操作员字符、操作员查询表 I.X是一种交互式(或解释器)命令。 LL.x是表示为x的文字。 K K.x是K系统函数 Cci是词汇范畴I的字符向量。 V一串州名称。 W一串最终州名称。 V中的X,我读到Cj中的一个字符,转到X[i;j]。 T 0(无踪迹)1(踪迹)。 E全球环境。 的全局堆栈。 Z(状态x 256)转移矩阵。
F F口译员。 N解释模式。 Q解释洗牌符号。 我转换字典列表。 J转换列表->;字典。 L加载并解释.f脚本。 S格式化F值并将其保存为.f脚本。 U更新堆栈(S)和环境(E)。 P对输入字符串进行标记化和解析以创建队列。 V评估令牌。 R从(";[";;...;";]";]";递归构造列表。)。 下标、索引、一元修正、二元修正。 E评估环境(X)中堆栈(Y)上的队列(Z)。 A将队列顶部应用于环境中的堆栈。 B评估符号。 K在环境中创建一个变量。 C处理已定义符号的值(J敏感)。 X应用n-ad f,将征募结果附加到堆栈。 Y应用n-ad f,将结果追加到堆栈。 Z应用n-ad f,将结果预先添加到队列中。 W将n-ad f应用于堆栈、队列、返回新堆栈,新队列。 T如果T是非空列表,则跟踪即将到来的步骤。 D显示轨迹。 F格式化堆栈。 G格式化堆栈上的元素。 H漂亮的打印机 O将符号转化为名称。
如果在.f或.j脚本中,解释器遇到单个 未匹配";,则对该脚本的评估终止。(类比 到.K脚本中的\。)。
要退出到K,或退出当前跟踪或停止,请输入 单个空格。通过使用按<;Return>;清除堆栈 空输入。
为Joy改编的序曲和阶乘函数的版本 语义学在这里和这里。
在Joy中,使用名称会导致与 要对堆栈执行的名称:
在F中,使用名称会导致与该名称相关联的值 放在堆叠上:
在Joy中,相邻名称必须用空格分隔,否则 等价物。对应的F码具有更大的视觉密度, 但也几乎同样简明扼要。例如,Reduce 合并器为:
有人可能会说,F处于乔伊和乔伊之间的中间位置, 它会积极地计算名称,而false则会破坏 将名称求值的语义分解为更小的步骤:
在false中,名称将其自身留在堆栈中。;拿到一个 名称,并将名称的值保留在堆栈上。好了!执行 价值观。
此外,F语义使得一个程序可以轻松地 修改另一个的代码:按名称调用程序,该程序 在堆栈上保留报价,修改报价,执行。
无论如何,应该注意的是,将F切换到Joy 语义学是一件微不足道的事情。C函数接受 定义的符号z的值、堆栈x和 队列y,并将其附加到堆栈:
其将z的内容预先添加到队列中。 后续处理将评估值的元素 一个接一个。
值得注意的是,在这两种方言中,有些原语 有名字的。例如,in是一个原始系统函数,因此:
注意:此开关已在F的脚本中实现, 即。J对于F语义是0,对于Joy语义是1。
F>;';MAP";o"; [[DUP COUNT[]TOP]DIP SWAP [报价Uncons DUP顶部 [CONS UNIT EVER FIRST SWONS] DIPD] Do POP POP REV]。
可以用这种方式编写程序,使用单词 在f脚本中定义。
在Joy中,报价既是一个列表,也是一个节目。所有程序 是列表,反之亦然。凭直觉,似乎确实有一个 [1 2 3]和[2+]之间的差异。不可能是 前者包含数据元素,后者包含数据 元素和函数,因为数字就是同样多的函数 作为+运算符。2和+都是从堆栈到 堆栈。
以清单形式报价和以清单形式报价之间的区别 报价单-即程序归结为:报价单类似于列表 当我们想要检查或操纵其部件或结构时;以及 当想要执行报价时,它就像程序一样。所以都是一样的 对象在某些上下文中可以显示为列表形式,在某些情况下可以显示为程序形式 在其他人身上。事实上,如果我们仅仅是 将其推送到堆栈上,而不考虑其结构或 执行属性,或者两者兼而有之,如果我们首先操作内容和 结构,然后执行它。
程序的价是一对整数。这个 该对中的第一个元素是堆叠价。这个 程序的堆栈价是它所使用的元素的数量 从堆栈中取出。第二个要素是排队价。 队列价数是它从 排队。
引用操作符';是唯一具有 非零队列价:它期望在 队列,它登记该队列并将其推送到堆栈上。因此,引用 堆叠价为1。
+运算符的堆栈价为2。它从 堆栈,并将总和推送到堆栈上。
程序的费用也是一对整数。 第一个元素是电堆电荷,第二个元素是 排队收费。
+有堆栈电荷1(它将单个元素推到 堆栈)和队列收费为0。DUP具有堆叠价1和 堆叠费2.交换有堆叠价2和 堆叠充电2。
!(无引号)具有堆叠价1和无限 Queue-Charge:它将报价从堆栈中取出并推送为 将许多元素放到队列中,就像报价中的元素一样。
`(DIP)的堆叠价为2,无穷大 队列收费:它从堆栈中去掉了两件事:报价和 元素X,并将第一个X推入,然后将引号推到 排队。
所有的基元都有非负电荷和价。一个 负值表示程序在底部运行 堆栈或队列的。
如果堆栈的元素少于(的绝对值 堆栈价),则发信号通知F堆栈错误。如果 队列的元素少于(的绝对值) 队列效价,则发信号通知F队列错误。
出栈程序期望在以下位置获得报价Q 堆栈的顶部,并将堆栈设置为q:
队列程序期望在以下位置的顶部有一个引号 堆栈,并将其附加到队列的末尾:
1 2 3[4 5 6]个队列7 8 9 1 2 3 7 8 9[4 5 6]。
出列程序要求在 队列,并将其推送到堆栈上:
1 2 3出队4 5 6[7 89] 1 2 3[7 8 9]4 5 6。
运算符堆栈-价堆栈-费用队列-价队列-费用 堆栈信息%1%0%0 取消堆栈%1信息%0%0 队列1 0 0-1 退出队列0 1-1 0。
$的实现是以下两个原语之一,这两个原语 递归调用F赋值器e。$是K函数 取x,环境,y,堆栈, 和z,即队列,定义为:
的实施。是另一个基元,该基元 递归调用F赋值器e。
M:{:[1=#y;e[x;();*y]1/下文 2=#y;(*y)。E[x;();y 1]1/索引 (4:*y)_in 4 6;';";G随机数:.";/无分配 3=#y;.@[y;2;{{*-1#e[*x;y,();x 1]1}[(x;y)]}[x]]/monad .@[y;2;{{*-1#e[*x;y,,z;x 1]1}[(x;Y)]}[x]}/DYAD。
其中y是堆栈顶部的报价,x 就是环境。
则y的计数为2。 Y的第一个元素,即10 20 30,乘以第二个元素的值 环境x中y的元素,即0 1。
模式是一个列表,它的头部是一个方案,其 尾巴是一个模板。
方案是方案的名称或列表。案例 名字的第一个字母很重要。如果为小写,则 名称与单个元素匹配。如果为大写,则名称必须出现 作为方案列表中的最后一个元素,并将匹配零或 更多的元素,即。列表的其余部分,其初始 元素由端子名称前面的方案匹配。
模板是一个列表。如果%s是中的符号 方案中也出现的模板,值匹配 用%s替换模板中的%s。
)将模式应用于堆栈,并将结果推送到堆栈上。 (将模式应用于堆栈,并将结果放在队列前面。 }将模式应用于队列并将结果推送到堆栈上。 {将模式应用于队列,并将结果放在队列前面。
尽管F支持DIP组合器作为基元, 可以将其定义为模式: