如何对 J 类 进行数组运算?
How do I perform array operations on J classes?
我正在研究 J 的面向对象工具。考虑以下极其人为设计的代码:
coclass 'Object'
create =: 3 : 'state =: 0'
increment =: 3 : 'state =: state + y'
destroy =: codestroy
cocurrent 'base'
objects =: (0 conew 'Object') , (0 conew 'Object') , 0 conew 'Object'
假设我想对 objects
数组中的每个对象调用 increment
方法。我如何以 J-tastic 的方式做到这一点?我能想到的唯一方法是中间动词:
o_increment =: 4 : 0
for_o. y do.
increment__o x
end.
)
3 o_increment objects
这可行,但不是很方便。有没有更好的方法?
因为对象引用是 J 形态的一部分,而不是语法,所以它们在 运行 时比其他数据更难操作。也就是说,对象引用被嵌入到名称中,而不是指定为自由参数。
因此,有两种方法可以调用对象数组的方法,并且都需要显式代码。第一种方法——除非在特殊情况下很少使用——是生成然后执行表示完全限定名称的字符串,包括直接(显式)定位。
3 apply&>~ 'increment_' ,L:0 objects ,&.> '_'
更常见的是在显式代码块中使用间接引用,使用预定义的局部变量之一作为定位。例如:
3 dyad def 'increment__y x'"0 objects
或者,等价地:
incrementObjs =: dyad define
increment__x y
)
objects incrementsObjs"0] 3
事实上,JSoftware 在版本 6 中做了一个主要的 backwards-compatibility-breaking change to the language 来使这个模式更方便。以前(即 v6 之前),您必须编写如下内容:
incrementObjs =: dyad define
o =. x. NB. x and y used to be spelled x. and y.
increment__o y NB. but increment__x. would raise an error
)
无论如何,请注意 incrementsObjs"0 objects
对显式 for_o. objects do.
循环的重新表述实际上根本不是 OOP 特有的;这是 J 面向数组的特性提供的标准迭代自动化。
这让我得到了你问题的真正答案:J 从根本上说是一种面向数组的语言,它的对象通常比它们更粗粒度使用更熟悉的语言,如 Java 或 C#。
在那些语言中,拥有一组对象是很常见的;在 J 中,拥有集合对象更为常见。也就是说,在某种意义上,主流OOP语言中的对象是"small"。在 J 中,对象很大,因为 J 中的 all 数据很大(我不是指物理上的 "big data",GB 意义上的:我指的是概念上的,哲学, ℕ 意义).
因此,实际最常见的表达问题的方式是:
coclass 'Object'
create =: 3 : 'state =: 0'
increment =: 3 : 'state =: state + y'
destroy =: codestroy
cocurrent 'base'
objects =: 'Object' conew 0 0 0
注意最后一行objects =: 'Object' conew 0 0 0
;原来是
objects =: (0 conew 'Object') , (0 conew 'Object') , 0 conew 'Object'
。
也就是说:我们创建了 一个对象,而不是一个包含 3 个对象的数组,一个包含 3 个值的数组.
另请注意,这是我更改的唯一一行代码。 "refactoring" 从处理标量值的对象到管理任意数量值的数组的对象进行了零字节的代码更改。
但是递增所有对象呢?之前,你不得不说:
3 dyad def 'increment__y x'"0 objects
现在,你只需说:
increment__objects 3
这就是为什么这是 J 1.
中 OOP 的标准方法
1 好吧,一个愤世嫉俗的人可能会说 J 的基本数组性质在某种程度上避免甚至与 OOP 的目标相冲突,并且 OO 特性在 90 年代后期 OOP 兴起期间,J 中可用的东西被附加上了 coughPerlcough,但我并不愤世嫉俗。至少不公开。
OOP 在 J 中占有一席之地,特别是在动态系统中组织大型组件;它的使用方式不同于基本哲学是 OO 而不是 AO 的语言。
inl_z_ =: (cocurrent@] ".@] [)"1 0
允许您运行在 1 或对象列表中编码
'state =: >: state' inl 对象
不同意 Dan,J 实际上非常擅长使用此函数处理对象列表。显然,您可以在调用代码之前预先过滤对象中的列表。在邮件列表中搜索 inlC(和 inlA)以了解 inl 的更高级用途,例如与调用方区域设置参数交互。
同意 Dan 的观点,与拥有可能的属性列表(然后是所有记录实例的 table)的替代方案相比,创建对象必须有充分的理由。一个很好的理由往往是有资源可以分配和释放
我正在研究 J 的面向对象工具。考虑以下极其人为设计的代码:
coclass 'Object'
create =: 3 : 'state =: 0'
increment =: 3 : 'state =: state + y'
destroy =: codestroy
cocurrent 'base'
objects =: (0 conew 'Object') , (0 conew 'Object') , 0 conew 'Object'
假设我想对 objects
数组中的每个对象调用 increment
方法。我如何以 J-tastic 的方式做到这一点?我能想到的唯一方法是中间动词:
o_increment =: 4 : 0
for_o. y do.
increment__o x
end.
)
3 o_increment objects
这可行,但不是很方便。有没有更好的方法?
因为对象引用是 J 形态的一部分,而不是语法,所以它们在 运行 时比其他数据更难操作。也就是说,对象引用被嵌入到名称中,而不是指定为自由参数。
因此,有两种方法可以调用对象数组的方法,并且都需要显式代码。第一种方法——除非在特殊情况下很少使用——是生成然后执行表示完全限定名称的字符串,包括直接(显式)定位。
3 apply&>~ 'increment_' ,L:0 objects ,&.> '_'
更常见的是在显式代码块中使用间接引用,使用预定义的局部变量之一作为定位。例如:
3 dyad def 'increment__y x'"0 objects
或者,等价地:
incrementObjs =: dyad define
increment__x y
)
objects incrementsObjs"0] 3
事实上,JSoftware 在版本 6 中做了一个主要的 backwards-compatibility-breaking change to the language 来使这个模式更方便。以前(即 v6 之前),您必须编写如下内容:
incrementObjs =: dyad define
o =. x. NB. x and y used to be spelled x. and y.
increment__o y NB. but increment__x. would raise an error
)
无论如何,请注意 incrementsObjs"0 objects
对显式 for_o. objects do.
循环的重新表述实际上根本不是 OOP 特有的;这是 J 面向数组的特性提供的标准迭代自动化。
这让我得到了你问题的真正答案:J 从根本上说是一种面向数组的语言,它的对象通常比它们更粗粒度使用更熟悉的语言,如 Java 或 C#。
在那些语言中,拥有一组对象是很常见的;在 J 中,拥有集合对象更为常见。也就是说,在某种意义上,主流OOP语言中的对象是"small"。在 J 中,对象很大,因为 J 中的 all 数据很大(我不是指物理上的 "big data",GB 意义上的:我指的是概念上的,哲学, ℕ 意义).
因此,实际最常见的表达问题的方式是:
coclass 'Object'
create =: 3 : 'state =: 0'
increment =: 3 : 'state =: state + y'
destroy =: codestroy
cocurrent 'base'
objects =: 'Object' conew 0 0 0
注意最后一行objects =: 'Object' conew 0 0 0
;原来是
objects =: (0 conew 'Object') , (0 conew 'Object') , 0 conew 'Object'
。
也就是说:我们创建了 一个对象,而不是一个包含 3 个对象的数组,一个包含 3 个值的数组.
另请注意,这是我更改的唯一一行代码。 "refactoring" 从处理标量值的对象到管理任意数量值的数组的对象进行了零字节的代码更改。
但是递增所有对象呢?之前,你不得不说:
3 dyad def 'increment__y x'"0 objects
现在,你只需说:
increment__objects 3
这就是为什么这是 J 1.
中 OOP 的标准方法1 好吧,一个愤世嫉俗的人可能会说 J 的基本数组性质在某种程度上避免甚至与 OOP 的目标相冲突,并且 OO 特性在 90 年代后期 OOP 兴起期间,J 中可用的东西被附加上了 coughPerlcough,但我并不愤世嫉俗。至少不公开。
OOP 在 J 中占有一席之地,特别是在动态系统中组织大型组件;它的使用方式不同于基本哲学是 OO 而不是 AO 的语言。
inl_z_ =: (cocurrent@] ".@] [)"1 0
允许您运行在 1 或对象列表中编码
'state =: >: state' inl 对象
不同意 Dan,J 实际上非常擅长使用此函数处理对象列表。显然,您可以在调用代码之前预先过滤对象中的列表。在邮件列表中搜索 inlC(和 inlA)以了解 inl 的更高级用途,例如与调用方区域设置参数交互。
同意 Dan 的观点,与拥有可能的属性列表(然后是所有记录实例的 table)的替代方案相比,创建对象必须有充分的理由。一个很好的理由往往是有资源可以分配和释放