Pull to refresh

Comments 25

1. Это нафиг никому не нужно.
2. Это легко повторить на любом современном языке.


Ну таки вообще говоря, да по обоим пунктам. :) Но аргументы будут.

Почему не нужно? Потому что современные языки для ввода или вывода данных стараются использовать форматы стандартные, типа JSON скажем, если мы говорим именно об обмене данными — т.е. вы в одном месте вывели, а в другом прочитали. И вывели на одном языке, а прочитали на другом. Поэтому ввод/вывод в проприетарном формате put data, пусть и документированном — если не прям совсем никому не нужен, то скорее всего будет мало популярен. Тут очевидная проблема — насколько я помню, в PL/1 не было структуры данных, которую часто называют хешмап, а также вероятно других структур данных. Соответственно, ваш формат вывода просто не может предусмотреть все возможные виды данных, которые есть в других языках — то есть, он либо ограничен одним языком, либо будут те или иные проблемы (эти проблемы есть и в случае JSON тоже).

Что же до легко повторить… ну конечно, не так чтобы прямо легко, сильно зависит от языка. В языках динамических, типа javascript — думается вообще раз плюнуть (потому что это прямой аналог того же JSON, вывод и ввод для которого уже имеется). Прямо в виде библиотеки. В языках с рефлексией, типа Java — тоже в общем не видно особых проблем (не считая наличия приватных полей, которые вообще говоря выводить не нужно, и что с ними делать — непонятно). Ну и во множестве языков есть специальные API для сериализации, которые нужны для того, чтобы передавать данные по разного рода каналам связи, сокетам и пр. — в этих случаях обычно есть нужный метод, который позволяет получить доступ к метаданным о переменных.
Даже для 2D работает =)
 auto y = [[1, 2],[1,2]];
UFO just landed and posted this here

Если хочется именно выражения выводить, то тут уже не так красиво:


string dump(string exprs)()
{
    import std.algorithm, std.conv;

    auto args = exprs.splitter(";").map!q{ "\"" ~ a ~ " = \"," ~ a }.joiner(",'\t',").to!string;
    return "import std.stdio; writeln(" ~ args ~ ");";
}

void main()
{
    auto x = 123;
    auto y = [[1, 2], [3, 4]];
    mixin(dump!q{x+45;y}); // x+45 = 168    y = [[1, 2], [3, 4]]
}

https://run.dlang.io/is/B7eVH9

UFO just landed and posted this here
Всё как вам хочется.

мне хочется так:

test:proc main;
declare i fixed, x(9) float;

do i=1 to hbound(x); x(i)=i; end i;
put data(x);

end test;

X(1)= 1.000000E+00 X(2)= 2.000000E+00 X(3)= 3.000000E+00 X(4)= 4.000000E+00
X(5)= 5.000000E+00 X(6)= 6.000000E+00 X(7)= 7.000000E+00 X(8)= 8.000000E+00
X(9)= 9.000000E+00
Конец программы
И так тоже нравится:

test:proc main;
declare (i,j) fixed, x(3,3) float;

do i=1 to hbound(x,1);
do j=1 to hbound(x,2);
x(i,j)=i+j;
end j;
end i;
put data(x);

end test;

X(1,1)= 2.000000E+00 X(1,2)= 3.000000E+00 X(1,3)= 4.000000E+00 X(2,1)=
3.000000E+00 X(2,2)= 4.000000E+00 X(2,3)= 5.000000E+00 X(3,1)= 4.000000E+00
X(3,2)= 5.000000E+00 X(3,3)= 6.000000E+00
Конец программы
UFO just landed and posted this here
К чему все эти слова? Да приведите, наконец, эти 10-15 строчек кода, которые повторяют два примера и все.
UFO just landed and posted this here
Console.Write и PUT DATA — это, конечно, одного поля ягоды. Для отладки вполне годятся.
Но Вы всерьез считаете, что так должна выглядеть строка отладочной печати?

x.ForEach((value, coords) => Console.Write($«x[{String.Join(», ", coords)}]={value}"));
Это быстро вставить?
По-моему, отладочная печать должна выглядеть не сложнее вот такого:

put skip data(x(1)); // печать строки из 3 элементов
put skip data(x(1,1)); // печать одиночного элемента

X(1,1)= 2.000000E+00 X(1,2)= 3.000000E+00 X(1,3)= 4.000000E+00
X(1,1)= 2.000000E+00

В статье я не утверждал, что невозможно. Но пока в приведенных примерах получается коряво, неудобно и, да, не универсально.
UFO just landed and posted this here
Извините, но Вы соскочили с темы, которая всего лишь об отладочном выводе с именами.
Кстати (см. соседний комментарий), в Питоне подумали и ввели что-то подобное. И не в библиотеку, а в язык.
UFO just landed and posted this here
Довольно глупо вместо ответа на вопрос, убеждать собеседника, что ему это не надо, а надо совсем другое. Особенно, если сам не можешь верно ответить =)

Например для отладки, если надо что то срочно поправить, а под рукой нет монструозной Студии.

Кстати, C# как то совсем уныло выглядит в плане форматированного вывода уже для 2D массива (
UFO just landed and posted this here
В последних версиях python-а есть в чем-то схожая с put data штатная возможность:
x = 3
l = [2, 4, 10]
s = 'Example'
print(f'{x=}, {x+2=}, {l=}, {s=}')
напечатает:
x=3, x+2=5, l=[2, 4, 10], s='Example'
Хотя например для печати индексов для каждого элемента массива нужно свой метод __repr__ определить или еще другими доп. средствами воспользоваться
Хорошо, вспомнили, что помогало отладке 50 лет назад и добавили ))
Но вот с индексами массива не очень. Для больших массивов легко сбиться со счета.
В Julia удобно сделан вывод массивов
julia> mat1 = [1 2 3; 4 5 6]
2×3 Array{Int64,2}:
 1  2  3
 4  5  6

А также для длинных массивов
Заголовок спойлера
julia> x = [j for j in 1:50]
50-element Array{Int64,1}:
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
  ⋮
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50

template haskell:
main = do
  let x   :: Int = 1
      xs  :: [Int] = [1, 2, 3]
      arr :: Array Int String = listArray (0, 2) ["a", "b", "c"]
  $(traceData 'x)
  $(traceData 'xs)
  $(traceData 'arr)

Вывод:
x = 1
xs = [1,2,3]
arr = array (0,2) [(0,"a"),(1,"b"),(2,"c")]

Сразу скажу, что можно любой формат вывода сделать, здесь используется стандартный Show.

Если есть вариант реализовать подобное не каким-то магическим способом, а средствами языка — то почему нет? Но встраивать подобную конструкцию в язык точно не стоит.
А для массивов 2d и старше автоматически индексы добавятся?
main = do
  let arr :: Array (Int, Int) String =
        listArray
          ((0, 0), (2, 2))
          [ "a0", "b0", "c0"
          , "a1", "b1", "c1"
          , "a2", "b2", "c2"
          ]
  $(traceData 'arr)

arr = array ((0,0),(2,2)) [((0,0),"a0"),((0,1),"b0"),((0,2),"c0"),((1,0),"a1"),((1,1),"b1"),((1,2),"c1"),((2,0),"a2"),((2,1),"b2"),((2,2),"c2")]
Чуток скобок многовато, но да — все отображено, для отладки то, что надо.
У меня самый громоздкий вариант структура-массив (т.е. есть и именованные поля и индексы):

declare
1 a(1:2),
2 a1 fixed,
2 a2 fixed,
2 b,
3 b1 (-5:3) fixed,
3 b2 float;

put data(b);

B(1).B1(-5)= 0 B(1).B1(-4)= 0 B(1).B1(-3)= 0 B(1).B1(-2)= 0 B(1).B1(-1)= 0 B(1).B1(0)= 0 B(1).B1(1)= 0 B(1).B1(2)= 0 B(1).B1(3)= 0 B(1).B2= 0.000000E+00 B(2).B1(-5)= 0 B(2).B1(-4)= 0 B(2).B1(-3)= 0 B(2).B1(-2)= 0 B(2).B1(-1)= 0 B(2).B1(0)= 0 B(2).B1(1)= 0 B(2).B1(2)= 0 B(2).B1(3)= 0 B(2).B2= 0.000000E+00

Получится подобное?
И?

#!/usr/bin/python3

x={"red" : "красный", "green": True}
print(x)


{'red': 'красный', 'green': True}


Получится такое? ;)
Как там в древних языках с ассоциативными массивами, например?

Просто 50 лет назад со средствами отладки было сложно, и оператор put был полезен. Раз в языки, с помощью которых решаются современные задачи, этот оператор не имплементирован — значит для решения современных задач он не нужен. Для отладки придумали отладчики — это удобнее, чем простыня из put. Массивы они всякие бывают… Многомерный массив в миллион элементов дампить так себе идея, например.
Sign up to leave a comment.

Articles