J语言初步,绝妙的符号系统,神的计算器
创始人
2024-06-02 10:32:54
0

文章目录

    • 简介
    • 算术符号和优先级
    • 赋值和比较
    • 复合动词
    • 动词列表
    • 理解阶乘!!

简介

J语言更像是一个大型符号系统,用以解决复杂的数学运算。所以在下载J语言之后,进入jconsole,就可以凭借感觉进行数学运算了。

其中加减乘除分别是+, -, *, %。但是玩过这么多编程语言,对这些常规的运算其实已经有些倦怠了,所以直接来个鬼酷一点的,事先说明,J语言中NB.后为注释。

   1 2 3 4 5 * 2  NB. 数乘列表
2 4 6 8 108 <: 7 8 9     NB. 数值和列表比较
0 1 17 8 9 < 9 8 7  NB. 列表和列表比较
1 0 0(+/ % #) 2.5 3.1 11 2         NB. 求均值
4.65fact=: 1: ` (* $:@<:) @. *    NB. 此为阶乘fact 5         NB. 计算5的阶乘
120

前三条很容易理解,就不解释了;第五条稍微有点难,也先不解释。这里先看看求均值的代码(+/ % #),其中%是个二元运算符——除法,这个除法作用在两个符号之间,其中+/用于数列求和,#则返回数列长度,二者相除就得到均值。

这个就是J语言符号运算的魅力,而且J语言提供了Android等版本,可以在手机上使用,下载地址:Android版本;IOS版本,在手机上的效果为

在这里插入图片描述

接下来,为了理解阶乘代码,先做一点最基础的J语言符号训练,主要包括三个内容,一是基础的运算符号;二是与if相关的语句;三是复合语句的概念。

算术符号和优先级

初学J语言,可以把运算符分为两类,即一元运算符和二元运算符,有的时候,同一个符号在进行一元或者二元运算的时候,会有不同的含义,例如%作为二元运算,表示除法,作为一元运算,表示求倒数

   % 5
0.23 % 5
0.6

下表中列出了常见的算术符号

+-*%^%:
一元负号正号取符号倒数e指数根号
二元乘方猜猜是什么

其中-作为一元运算表示取负,而J语言中的复数用下划线表示,即_1表示−1-1−1。

和其他语言不同,J语言中乘法并不比加法优先,如果想更改二元运算的顺序,可以使用括号。而一般来说,一元运算比二元运算有着更高的优先级。

   2 * 3 + 4      NB. J语言中乘法并不比加法更优先
14(2 * 3) + 4    NB. 但括号还是优先的
102 * * -3       NB. * -3取-3的符号,为-1
_2                NB. 然后2乘以负一得到-2

赋值和比较

J语言中,通过=:进行变量赋值,而且作为函数式语言,=:不仅可以赋值变量,也可以赋值函数

   a =: 5   NB. 把5赋值给aa
5b =: -   NB. 把运算-赋值给bb a      NB. 相当于 - a
_5a b a    NB. 相当于 a - a
0type 'b'
┌────┐
│verb│
└────┘type 'a'
┌────┐
│noun│
└────┘

type可以返回符号的类别,在其他语言中,我们一般把-称作运算符,但在J语言中,则称作动词;而变量则为名词。在J语言中,还有副词、连词等。

=:用于赋值,而其他语言中常用的=在J语言中则表示相等

符号含义符号含义
=判断相等=:赋值
<小于<:小于等于
>大于>:大于等于

复合动词

通过=:可以进行赋值,而且可以赋值为名词,还可以赋值为动词,例如<:>:分别表示减1和加1,但容易记混,所以下面新建两个函数表示

   addOne =: >:minusOne =: <:addOne 10
11minusOne 10
9

这个本来没什么,不过在多个动词连接时却出现了问题,比如想实现类似1x+1\frac{1}{x}+1x1​+1的功能,如果x=5,那么就是下面这种

   >: % 5
1.2

那么如果想做一个复合函数,也理应是test =: >: %,但下面显然是错的

   test =: >: %test 5
1

错误的原因也很离谱,test 5实际上执行的是5 >: % 5,其中%被翻译为单目运算符取倒数;>:被翻译为双目运算符,用于比较,最后自然5>155>\frac 1 55>51​为真,即返回1。

换言之,:> %在未指定输入的情况下,是有歧义的。

为了避免这个尴尬的问题,通过@对动词进行复合是个好办法

   test =: >: @ %test 2
1.5

其中,@就起到了函数复合的作用,相当于把函数fff和ggg,变为f(g(x))f(g(x))f(g(x))。

动词列表

如果想用同一个动词,处理多个不同的值,那么可以先用不同的值做一个列表。

   % 2 3 4
0.5 0.333333 0.25

但是,若想用不同的动词,处理同一个数值,那可能就不能这么直接列出来了,因为按照J的脾气,肯定先复合了再说,想做一个动词列表,那么需要用括号,然后中间用,或者`分隔,类似下面这种

   (%, ^) 5
0.2 148.413

需要注意,中间的逗号如果没有的话,那么最终的结果还是复合,只不过换了个复合的方法

   % ^ 5
0.00673795(% ^) 5
0.0336897

上面执行的计算是1e5\frac{1}{e^5}e51​,下面执行的运算是5/e55/e^55/e5,即()把其左侧的运算符理解为了双目计算,并将输入的5分成两份分别送到了表达式两端。

(,)虽然能实现列表,但是这个列表也有一个问题,即无论何时都会一起使用。正常列表,比如[1,2,3],那讲道理我把其中的2提取出来专门处理肯定也是没问题的,但函数上面的函数列表好像不太行。

为了解决这个问题,J语言提供了`…@.语句。

由于`在Markdown中是负责高亮的,所以`自己就没法高亮了……具体使用方法,直接看下面的代码

   test =: % ` ^(test@.0) 3
0.333333(test@.1) 3
20.0855

理解阶乘!!

再有了上面这些代码的积淀之后,只需在知道两件事就可以看懂阶乘的代码了,这两件事分别是J语言中的两类特殊函数。

一类是1:函数,表示常量函数,1:的返回值永远是1;相应地_3:返回值永远是-3,这样的函数共有19个,值从-99

另一类则是创建递归函数必不可少的$:,表示调用自身。

接下来就回顾一下阶乘代码

fact=: 1: ` (* $:@<:) @. *

其中*用于返回符号,当输入值x大于1时,* x=1,当输入值x=0时,* x =0

如果*x=0,那么fact就选择左边的1:函数,此函数无论输入什么,返回值都是1。

如果*x=1,那么就选择右侧的(* $:@<:),此函数最外层是(* ),将输入的值xxx变为x * ($:@<:)$:表示调用自身,:<减一,二者结合就成了f(x-1)

至此,也就明白了阶乘是怎么来的,同时也基本上算是上了J语言的船。

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...