Немного истории

Краткий обзор J

3 5

$

0

3 5

$

1 2 3

1 2 3 1 2

3 1 2 3 1

2 3 1 2 3

a

=:

4

a

4

4 5 3 6

4 5 3 6

avg

=:

+

/

%#

avg

+

/

#

%

a

=:

5 3 7 0 2 4

avg a

3.5

2

*

3

+

4

14

(

2

*

3

)

+

4

10

avg

=:

+

/

%#

d

=:

>.

/

++

/

%#

d a

10.5

Примеры

1. INNER JOIN

CREATE TABLE Customers (ID INT, Name TEXT, Age INT, Salary INT) CREATE TABLE Orders (OID INT, Date DATETIME, CustomerID INT, Amount INT)

SELECT * FROM Orders o INNER JOIN Customers c ON o.CustomerID = c.ID AND o.Amount < 2000

createTable

=:

[:|:,.

&

a:



union

=:

(

[:{.[

)

,:[:

(

[:<[:;]#

~

~:

&

a:

)

"

1

(

[:{:[

)

,.

(

[:{:]

)

{

~

(

[:{.]

)

i.[:{.[



insert

=:

[

union

[:

(

{.,:

(

[:

(

[:<[:

(

]$

~

[:

1

&

,#

)

>

)

"

0

{:

))

[:|:[:>]



rows

=:

{.

(

[:<,:

)

"

1 1

[:|:[:

(

[:<

"

1

[:,.>

)

"

0

{:



value

=:

[:

(

]

`

{.

@.

(

[:

1

&

=#

))

[:,[:>[

(((

[:<[

)

=[:{.]

)

#[:{:]

)

[:>]



pr

=:

[:,[:

((

[:>[

)((

[:<

(

[:>[

)

,.[:>]

)

"

0 0

)

"

0 1

[:>]

)

/

[:

(

[:<[:

rows

>

)

"

0

]



join

=:

1

:

'((([:{.[:>{.),:[:([:<(>

"

0))

"

1[:{:[:1 2 0&|:[:>([:,u

"

0)#]) (pr y))'

Customers

=:

createTable 'ID'

;'

Name'

;'

Age'

;'

Salary'

Orders

=:

createTable 'OID'

;'

Date'

;'

CustomerID'

;'

Amount'



Customers

=:

Customers insert

(

<'

ID'

;

1

)

,

(

<'

Name'

; '

Ramesh'

)

,

(

<'

Age'

;

32

)

,

(

<'

Salary'

;

2000

)



Customers

=:

Customers insert

(

<'

ID'

;

2

)

,

(

<'

Name'

; '

Khilan'

)

,

(

<'

Age'

;

25

)

,

(

<'

Salary'

;

1500

)



Customers

=:

Customers insert

(

<'

ID'

;

3

)

,

(

<'

Name'

; '

kaushik'

)

,

(

<'

Age'

;

23

)

,

(

<'

Salary'

;

2000

)



Customers

=:

Customers insert

(

<'

ID'

;

4

)

,

(

<'

Name'

; '

Chaitali'

)

,

(

<'

Age'

;

25

)

,

(

<'

Salary'

;

6500

)



Customers

=:

Customers insert

(

<'

ID'

;

5

)

,

(

<'

Name'

; '

Hardik'

)

,

(

<'

Age'

;

27

)

,

(

<'

Salary'

;

8500

)



Customers

=:

Customers insert

(

<'

ID'

;

6

)

,

(

<'

Name'

; '

Komal'

)

,

(

<'

Age'

;

22

)

,

(

<'

Salary'

;

4500

)



Customers

=:

Customers insert

(

<'

ID'

;

7

)

,

(

<'

Name'

; '

Muffy'

)

,

(

<'

Age'

;

24

)

,

(

<'

Salary'

;

10000

)





Orders

=:

Orders insert

(

<'

OID'

;

102

)

,

(

<'

Date'

; '

2009

-

10

-

08'

)

,

(

<'

CustomerID'

;

3

)

,

(

<'

Amount'

;

3000

)



Orders

=:

Orders insert

(

<'

OID'

;

100

)

,

(

<'

Date'

; '

2009

-

10

-

08'

)

,

(

<'

CustomerID'

;

3

)

,

(

<'

Amount'

;

1500

)



Orders

=:

Orders insert

(

<'

OID'

;

101

)

,

(

<'

Date'

; '

2009

-

11

-

20'

)

,

(

<'

CustomerID'

;

2

)

,

(

<'

Amount'

;

1560

)



Orders

=:

Orders insert

(

<'

OID'

;

103

)

,

(

<'

Date'

; '

2008

-

05

-

20'

)

,

(

<'

CustomerID'

;

4

)

,

(

<'

Amount'

;

2060

)



Customers

ID Name Age Salary 1

2

3

4

5

6

7

Ramesh

Khilan

kaushik

Chaitali

Hardik

Komal

Muffy

32

25

23

25

27

22

24

2000

1500

2000

6500

8500

4500

10000



Orders

OID Date CustomerID Amount 102

100

101

103

2009-10-08

2009-10-08

2009-11-20

2008-05-20

3

3

2

4

3000

1500

1560

2060



((

[:

2000

&

>

'Amount'

&

value

)

*.

'CustomerID'

&

value

=

'ID'

&

value

)

join Customers

; <

Orders

ID Name Age Salary OID Date CustomerID Amount 2

3

Khilan

kaushik

25

23

1500

2000

101

100

2009-11-20

2009-10-08

2

3

1560

1500



2. Решатель судоку

i

=:

,

((

,|:

)

i.

9 9

)

,,.

/

,.

/

i.

4

$

3



c

=:

(

#=[:#~.

)

@

-.

&

0



t

=:

[:

((

[:*

/

_9:

c

\

]

)

"

1

#]

)

i

&

{+

"

1 1

(

>:i.

9

)

*

/

[:

i

&

=i.

&

0



r

=:

[:,

`

$:

@.

(

0:e.,

)

[:;

(

<

@

t

)

"

1



s

=:

9 9

&

$

@

r

@

,



]

m

=:

9 9

$".

"

0

'200370009009200007001004002050000800008000900006000040900100500800007600400089001'

2 0 0 3 7 0 0 0 9

0 0 9 2 0 0 0 0 7

0 0 1 0 0 4 0 0 2

0 5 0 0 0 0 8 0 0

0 0 8 0 0 0 9 0 0

0 0 6 0 0 0 0 4 0

9 0 0 1 0 0 5 0 0

8 0 0 0 0 7 6 0 0

4 0 0 0 8 9 0 0 1

s m

2 8 4 3 7 5 1 6 9

6 3 9 2 1 8 4 5 7

5 7 1 9 6 4 3 8 2

1 5 2 4 9 6 8 7 3

3 4 8 7 5 2 9 1 6

7 9 6 8 3 1 2 4 5

9 6 7 1 4 3 5 2 8

8 1 3 5 2 7 6 9 4

4 2 5 6 8 9 7 3 1



Более короткие решения

http://nsl.com/k/sudoku/aw3.k

Это решение занимает всего 72 (!!!) символа. Но это решение Артура Уитни, создателя языка К. И решение на К. Артур Уитни – Бог программирования, соревноваться с ним не имеет смысла.

Мое решение содержит незначащие пробелы, вокруг присваивания (минус 10 символов) и можно еще «заинлайнить» глаголы, что тоже поможет выиграть несколько символов. Но не хочу ради краткости ломать красивый и понятный код ))



Уверен, что для J существуют способы написать короче, а у меня сказывается недостаток опыта.

Показанный выше код состоит из 148 символов, включая пробелы и переносы строк. Есть решения короче. Например:Это решение занимает всего 72 (!!!) символа. Но это решение Артура Уитни, создателя языка К. И решение на К. Артур Уитни – Бог программирования, соревноваться с ним не имеет смысла.Мое решение содержит незначащие пробелы, вокруг присваивания (минус 10 символов) и можно еще «заинлайнить» глаголы, что тоже поможет выиграть несколько символов. Но не хочу ради краткости ломать красивый и понятный код ))Уверен, что для J существуют способы написать короче, а у меня сказывается недостаток опыта.

3. Prolog

frq

=:

[:-.[:

(

2:|+

/

)

\

''''

&

=



sp

=:

(

#

@

[

)(

[:<[}.[:>]

)

"

0 0

[

(

]<

/.

~

[:+

/\

E.*.[:

frq

]

)

,



spf

=:

[:<[:

(

[:

','

&

sp

[:-.

&

')'

=

&

'('

{

"

0 1

,.

&

','

)

>



cl

=:

#

~

[:-.e.

&

(

33

{.

a.

)

*.

frq

parse

=:

[:

(

[:<[:

((

spf

@

{.

)

,

(

}.

`

(

[:<[:

(

[:<[:

spf

"

0

[:

'),'

&

sp

>

)

"

0

[:

');'

&

sp

[:>{:

)

@.

(

2:=#

)))

[:

':-'

&

sp

>

)

"

0

_1:}.[:

'.'

&

sp cl



isVar

=:

[:

(

91

&

>*.

64

&

<

)

[:

a.

&

i.[:{.>



replace

=:

((

]i.

~

[:{.[

)

{

(

[:{:[

)

,]

`

(

[:<[$:[:>]

)

@.

(

[:

32

&

=[:

3

!:

0

[:>]

))

"

2 0



gp

=:

[:>[:{.>



gv

=:

[:

(

#

~

[:+.

/"

1

isVar

"

0

)

,.



suit

=:

(

[

(

0:

`

((

[:

(

#=[:#[:~.[:{.|:

)

[:~.[:

(

#

~

[:-.[:

isVar

"

0

[:{:|:

)

gv

)

*.

(

[:*.

/

[:+.

/

[:

(

isVar

"

0

,=

/

)

,:

))

@.

((

[:#[

)

=[:#]

))

[:

gp

]

)

"

1 0

#]



sr

=:

[

(

]

(

replace

~

[:|:]

)

"

2

[:

((

[:-.[:

isVar

{:

)

"

1

#]

)

[

gv

~

[:

gp

]

)

"

1 0

suit

groupVars

=:

[:

(

[:<]$

~

2:,

~

[:-:#

)

"

1

[:>[:

(

[:<[:;

(

>

@

[

)(

[:<,

"

1 1

)

"

1 2

(

>

@

]

))

/

]<

/

.

~

[:{.|:



isRuleTrue

=:

(

[:+.

/

(

[:*.

/

]

(

isTrue

~

[:>]

)

"

1 0

[:>[

)

"

0 1

)

`

(

0:<[:#

getVarsFromRule

)

@.

(

0:<#

@

gv

@

;

@

;

@

[

)



isTrue

=:

]

((

a:

&

e.

@

]

)

+.[:+.

/

[

(

isRuleTrue

~

[:>]

)

"

1 0

[:-.

&

a:

]

)

[:{:[:|:[:-.

&

(

a:

,

a:

)

[:

(

0 2

$

a:

)

&

,[:>

sr

getVars

=:

;

((

[:<[:~.

(

>

@

{.

@

[

)

gv

[:

gp

]

)

`

((

>

@

{.

@

[

)

$:

(

<

@

<

@

gp

@

]

)(

[

replace

~

[:|:[:>]

)

"

0 0

(

}.

@

[

)

getVarsFromRule

~

[:>[:{:[:>]

)

@.

(

[:<:[:#[:>]

))

"

1 0

sr

getVarsFromRule

=:

]

((

[:{.]

)

#

~

[

(

isRuleTrue

~

[:>]

)

"

1 0

[:{:]

)

[:|:[

(

],[:<[

replace

~

[:|:[:>]

)

"

1 0

[:]

`

groupVars

@.

(

0:<#

)

[:~.[:;[:;]

(

[:<[

getVars

~

[:>]

)

"

1 0

[:;[



goal

=:

(

[:<

S:

0

[:{.[:

parse

[:,

&

'.'

]

)(

[:{

&

(

>

'No'

;

'Yes'

)

isTrue

)

`

(

[:

(

]

`

((

>

@

{.

)

,[:

' = '

&

,[:>{:

)

@.

(

2:=#

))

"

1

[:>

getVars

)

@.

(

[:+.

/

[:

isVar

"

0

[

)(

[:

parse

[

)



prolog_code

=:

0

:

0

male(jeff).

male(fred).

female(mary).

parents(jeff, vince, jane).

parents(mary, vince, jane).



sister_of(X,Y) :- female(X),

parents(X, F, M),

parents(Y, F, M).



)



prolog_code goal 'sister_of(mary, fred)'

No

prolog_code goal 'sister_of(mary, X)'

X = jeff



X = mary

Заключение

Ссылки

J – самый ненормальный и самый эффективный язык из известных мне языков. Он позволяет быстро разрабатывать, а также вызывать ненормативную лексику у людей, незнакомых с ним и смотрящих на код.J слишком необычный. И сложный для изучения. У людей, сталкивающихся с J не хватает мотивации, чтобы его изучить. Синтаксис непривычный.В этом посте я хотел помочь вам заглянуть дальше, что будет, если вы его изучите и чем он интересен. По своему опыту знаю, что преимущества этого языка сразу не очевидны. В посте я не собираюсь останавливаться на разборе конструкций. Только в обзоре. Предлагаю просто окунуться в примеры, попробовать ощутить мощь языка. Узнать, чем прекрасен язык, без изучения. Писать статьи, обучающие программированию на нем – дело сложное и думаю, не нужное. Он не так прост, чтобы это сделать кратко, а с обучающими материалами на официальном сайте нет никаких проблем. Главное – желание. Им и займемся.До J был APL . Язык APL разработан Кеннетом Айверсоном во время преподавания в 50-х годах в Гарварде вычислительной математики. Специально для преподавания он разработал свою нотацию. Далее этот язык был перенесен на машины и стал известен как APL (скромное: A Program Language). APL работает с массивами и оптимизирован под работу с ними.У языка APL есть небольшой недостаток. Операции обозначаются нестандартными символами. Для работы с ним нужна специальная клавиатура. Таким образом, назрела необходимость создать новый язык, более дружественный к стандартным устройствам ввода. Айверсон инициировал создание диалекта APL, который использует ASCII символы. Так Кеннет Айверсон совместно с Роджером Хуэем в начале 90-х создали язык J. В это время от команды Айверсона «откололся» Артур Уитни. Он имел разногласия по поводу того, как создавать J, и занялся созданием своего языка – K . Который также стал успешным языком.J – функциональный язык. Но язык не обычный, не классический функциональный. Не лиспоподобный. Единица данных — n-мерный массив, а не список.J является интерпретатором (в этой реализации). С динамической типизацией.Выражения строятся из глаголов, имен существительных, наречий, герундиев, союзов и прочего. Нас в данном посте будут интересовать глаголы (аналог функции/операции) и имена существительные (данные). Имена существительные – это не совсем данные, как в императивных языках. Они имутабельны. Таким образом, то, что в J называют присвоением, скорее является «именованием».Имя существительное – это n-мерный массив. Создать имя существительное можно, например, так:Мы получаем двумерный массив 3 на 5, состоящий из нулей. Можно получить массив любой мерности. Частным случаем является массив нулевой мерности — это скаляр. Одномерный массив – вектор. Таким образом, единица данных в J – n-мерный массив. Чтобы построить массив, заполненный не нулями, а нужными нам числами, после знака $ мы можем записать в строку нужные данные через пробел. Например строка:Создаст и выведет массив 3 на 5 и заполнит по очереди повторяющейся последовательностью 1 2 3:Для создания скаляра достаточно одного числа:Здесь я уже показал, как присваивается имя. Т.е.у нас уже равно. Для создания вектора достаточно писать числа в строку через пробел:Теперь о типах. В J кроме мерности массива, есть тип его элементов. Т.е. элементы всегда однотипные. Числовых типов несколько: логический (0, 1), целый, целый с любым количеством знаков, рациональный, действительный, комплексный. Также вместе с числовыми типами есть специальные числа: минус бесконечность, бесконечность, неопределенность. Динамическая типизация J замечательно подходит для математических операций – он на каждой операции сам определит, какие в нем числа. Например, если к матрице целых чисел применить квадратный корень, то можем получить либо действительные, либо комплексные числа. В зависимости от элементов первоначального массива.Также в J, кроме числовых типов есть1) символ (literal). В J также можно обрабатывать текст. Текст в случае J – это вектор из символов. Чтобы задать символ, нужно его заключить в одинарные кавычки. Чтобы задать вектор из символов – достаточно текст заключить в одинарные кавычки.2) бокс (коробка, boxed) – это упакованный тип. Т.е. любую матрицу можно упаковать и получить бокс. А из боксов можно составить массив. С помощью боксов, таким образом, можно создавать деревья.И еще несколько специальных типов, рассматривать которые не будем.С существительными разобрались. Теперь, что представляют собой глаголы.Глагол похож на операцию в математическом выражении в других языках. В J глаголы бывают двух видов: монадные (monad) и диадные (dyad). Это аналогично унарной и бинарной операциям. И это дает замечательную возможность: для создания глаголов не нужны имена для входных данных. Входных данных всегда одно или два – правое и левое.Есть специальные правила, как формировать в одну строку глагол из других глаголов, не используя при этом никаких имен переменных.Итак, первый стандартный пример:Глагол– среднее арифметическое вектора. Обратите внимание на его тело – всего 4 символа. Здесь у нас всего три глагола – сложить числа (), взять длину вектора () и разделить первое на второе ().Создадим вектор и применим к нему наш глагол:Получили среднее арифметическое вектора.Как же происходит эта магия? В J используются такие простые правила. Во-первых, операции в J не имеют приоритета и выполняются. Если мы напишем выражение:Получаем 14, а не 10. Что, в общем-то, упрощает построение выражений. Если надо изменить порядок – используются скобки:Не пугайтесь, это только что были выражения, вычисляющие значения напрямую, а когда мы писали, то мы задавали глагол, комбинируя глаголы.Теперь разберем, как работает глагол вычисления среднего арифметического.Когда глагол состоит из трех глаголов подряд, то сначала применяются крайние глаголы к существительным, а потом средний глагол к правому и левому по отношению к нему результату.Вот так:Если глагол состоит из 5 глаголов, то сначала выполняются три правых, как показано выше, потом берутся два левее и в таком же порядке выполняется дальше. Например, глагол взятия максимального из двух элементов: «>.». Следовательно, максимальный из списка: «>./»И напишем глагол, который находит сумму максимального значения и среднего арифметического:Применяем к вектору:Как это работает:Обратите внимание, что когда я пишу «как это работает», то я не имею ввиду, что знаю, в какой последовательности выполняет эти глаголы J. Я только объясняю смысл, как надо понимать такую строку глаголов. Строкой глаголов мы говорим,мы хотим. А— решает J.Выше я описал только одно из правил построения выражений. Просто ради того, чтобы вы уловили суть, как это возможно, кратко описывать в строку сложные алгоритмы и в чем кроется секрет лаконичности J. Естественно, J больше и описывать в посте всё нет смысла.Иногда невозможно описать задачу так, чтобы глаголы принимали только два простых массива как аргументы (левый и правый). Иногда нужно писать глаголы, аналоги функций с бОльшим количеством аргументов. Это можно обойти боксированием. Т.е. можно задавать вектор боксов, в которых лежат, по сути, ряд разных значений, аналогично входным параметрам функции в других языках. А в глаголе их можно оттуда доставать и распаковывать. Также в глаголах реализуется рекурсия.Описанная выше форма записи глаголов в J называется таситной (tacit).Теперь несколько примеров, без объяснения, как они работают.Рассмотрим такой пример на SQL. У нас есть две таблицы:Как-то их заполняем. И такой запрос:Специально соединяю таблицы не по равенству, а через более сложный предикат, чтобы немного усложнить задание.И попробуем сделать то же самое на J.В общем-то, это весь код, позволяющий решить данную задачу. Нужные глаголы есть. Создадим и наполним таблицы:Проверим, что у нас в таблицах:И запрос с предикатом:Вот так всё просто. Обратите внимание, что J — язык общего применения и в нем нет средств для обработки реляционных данных. Код, который выше, до создания и наполнения таблиц — вся логика. join может принимать любой предикат.Пример на самом деле не сложный, т.к. массивы в чем-то схожи с таблицами, а боксы (коробки) J рисует в прямоугольниках, что позволяет сразу таблицы и отображать.Это весь код. Создадим входную матрицу:Применяем к ней глагол и получаем решение:Хочется показать код на J для более практичной задачи и не близкой к матрицам/массивам. Слышал сомнения, что векторный подход подходит для парсинга. Пришла идея выбрать простую задачу для поста, решение которой связано с парсингом. Реализую Prolog. Точнее, не весь Prolog, т.к. задача не практическая и времени и усилий много тратить не хочется. Это будет подмножество Prolog-а, чтобы показать, что в принципе таситная форма записи годится и для таких задач. В этом Prolog-е, если его так можно назвать, не будет даже отсечения. Только простые факты и правила, операция «и», «или». Итак, код:Это весь код. Собственно, парсер в первой части решения. Задача парсинга такого простого Prolog-а, конечно, примитивна. Но всё же, J можно применять для парсинга. И для более сложных задач парсинга.Единственная «сложность» в парсере — Prolog допускает создание атомов из произвольных символов, если они берутся в одинарные кавычки. Иначе парсер был бы значительно короче. И еще, я специально не пользуюсь никакими библиотечными глаголами. Для того, чтобы вы оценили мощь самого языка, насколько быстро можно что-то написать с нуля. Есть и библиотека для работы с текстом. Есть библиотека для работы с регулярными выражениями.Зададим код на Prolog-е:И пару вопросов.«Приходится ли Мери сестрой Фреду?»:«Кому Мери приходится сестрой?»:Надеюсь, вы прониклись тем, как на J можно кратко решать сложные задачи. На счет легкости, у вас, возможно, сомнения.Цель примеров – показать код в таситной форме. Вы обратили внимание на то, что в коде практически нет каких-то нестандартных библиотечных глаголов? Весь код почти состоит из пунктуации. Это элементарные глаголы J. Конечно, никто не заставляет писать так, не вводя свои глаголы, не давая им осмысленных имен. Но высокоуровневость J предрасполагает в силу краткости кода не вводить новые имена. Цена усилий на создание нового кода мала, что приводит к тому, что реже хочется код прятать за именем. В целом со временем это приводит к тому, что программист на J читает одни и те же глаголы, которых не так много, и со временем учится всё лучше и лучше читать код. Код становится яснее и яснее.Я думаю, что каждый программист, работающий на каком-то мейнстримном ООП-языке, с грустью согласится, какой сейчас ад с библиотеками и фреймворками. Правильные практики программирования призывают инкапсулировать код, прятать за осмысленными именами. Если усилия на создание кода достаточно велики – больше появляется имен. И когда вы, например, приходите в новый коллектив работать с проектом, от языка в коде мало что остается – вам нужно изучать новые для вас сущности, всё, чему дали имена предыдущие программисты. Изучение нового языка всегда грозит изучением библиотек, а их количество стремительно растет. J не решает эту проблему, но отдаляет.J как язык имеет достаточно высокий порог вхождения. Поначалу он практически не читаем. Вы, изучив все глаголы, сможете с трудом на нем писать, но читать даже свой код не сможете. Но со временем, сможете это делать всё легче и легче. Это не произойдет с другими языками.Также, надо упомянуть, что это не значит, что J имеет слабую поддержку и в нем недостаточно библиотек. Много уже наработок, от работы с excel-файлами, базами данных, до работы с видео. Также J мультипарадигменный, на нем можно писать не только в tacit форме, но и в императивной. С циклами и ветвлениями. С обработкой ошибок. J поддерживает ООП.Работа с J напоминает не кодирование, а вывод формулы. Вы, поначалу, будете всматриваться в код, скорость набора значительно ниже. Но при всем при этом, результат даже поначалу будет получаться быстрее, чем в других языках. Даже не имея сверхбольшого опыта и читаемости кода, через время окажется, что сесть решить задачу на J кажется гораздо проще, чем решить на любом другом, более знакомом языке. Работа с J напоминает работу с мощным калькулятором, а не языком программирования. У вас нет ощущения, что вы создаете что-то на века. Скорость получения результата дает больше смелости в кодировании и вы легче пробуете различные варианты.Благодаря этому у J есть ниша – обработка данных, особенно в финансовой сфере. На J легко «вращать» данными, проверять различные гипотезы. А если нужно – сохранить скрипт и использовать как программу. J удобен в проектах для обработки данных. Там где нужны сложные алгоритмы. Причем, под сложностью алгоритмов я подразумеваю «полезную сложность», т.е. сложность преобразования данных, а не алгоритмы для оптимизации. При всём при этом, J достаточно производителен. Пусть вас не пугает то, что он интерпретатор. Интерпретатор он только в том плане, что выполняет выражения построчно. Но если в строке записано выражение глагола, то он его выполняет один раз, запоминая, а далее при применении глагола к данным, работает уже быстро. Т.к. обрабатываются обычно данные большого объема, то оптимизации в J показывают неплохую производительность. Также J может работать с библиотеками, написанными на других языках. Что позволяет оптимизировать проблемные места.Этот язык благодаря своим свойствам, хорош для создания прототипов. При этом прототип имеет большие шансы не быть переписанным, т.к. или производительность будет устраивать, или можно провести оптимизации только проблемных участков.Это всё хорошо, но есть одна проблема в использовании J в командных проектах – мало специалистов. Если вы решите использовать J в проекте, то высокая вероятность, что не найдете людей.И, тем не менее, J можно использовать не только для командной работы. Он дает сильный обучающий эффект. Работа с J меняет взгляды на алгоритмы в целом, «выворачивает сознание». Оказывает положительное влияние на работу с другими языками.Также этот язык очень удобен для работы, как вспомогательный язык. У меня среда J всегда открыта и я не пользуюсь калькулятором или excel. Когда нужно распарсить что-то или сгенерировать код для другого языка – J – отличное средство.1. Официальный сайт: www.jsoftware.com 2. Предлагаю почитать отличную статью — Язык программирования J, введение