LINUX.ORG.RU

История изменений

Исправление MOPKOBKA, (текущая версия) :

Ну да, специально смешиваю. Цель была показать сложность в работе с C.

У С просто возможностей большей. Если нужна скорость, то в Golang придется руками вычислять индексы. Ну можно понять почему ты называешь это сложностью.

Чтобы передать непрерывный массив, разве не так?

Ты наверное такой код хотел написать?

int print_array(int width, int height, int array[width][height])
Можешь передавать в array переменную которая объявлена как int new_array[10][20], не обязательно ее делать VLA. Но если размер new_array определяется переменными, то его объявление будет таким int new_array[size1][size2].

А обработка ошибок в Go — это благодать. Многословность компенсируется необходимостью явно проверять ошибки и избавляет от усложнённого потока выполнения, когда при простом чтении не знаешь когда произойдёт обрыв.

Если код ответственно все проверяет, то он будет разростаться в несколько раз, за этими проверками не видно самого кода.

Есть схожая проблема у ручного управления памятью, невозможно писать элегантные функции как в функциональном программировании, даже хвостовая рекурсия ограниченна из за стадии очистки (в Golang тоже из за defer?).

Лучше взять пример с логикой или обработкой сущностей, но мне не хочется придумывать их сейчас, поэтому давай арифметику возьму, на ней тоже хорошо видно.

Вот был понятный код с исключениями, такой:

try {
  l = sqrt(pow2(x1 - x2) + pow2(y1 * y2))
} catch (BigNumberException e) {
  log write
  exit or return
}
Или такой:
try {
  a = pow2(sub(x1, x2))
  b = pow2(mul(y1, y2))
  c = sqrt(add(a, b))
} catch (BigNumberException e) {
  log write
  exit or return
}
Без исключений он превращается в:
r1 = x1 - x2
if r1 == error {
  log write
  exit or return
}

r2 = pow2(r1)
if r2 == error {
  log write
  exit or return
}

r3 = y1 * y2
if r3 == error {
  log write
  exit or return
}

r4 = pow2(r3)
if r4 == error {
  log write
  exit or return
}

r5 = r1 + r4
if r5 == error {
  log write
  exit or return
}

r6 = sqrt(r5)
if r6 == error {
  log write
  exit or return
}

А это еще простой пример.

Исправление MOPKOBKA, :

Ну да, специально смешиваю. Цель была показать сложность в работе с C.

У С просто возможностей большей. Если нужна скорость, то в Golang придется руками вычислять индексы. Ну можно понять почему ты называешь это сложностью.

Чтобы передать непрерывный массив, разве не так?

Ты наверное такой код хотел написать?

int print_array(int width, int height, int array[width][height])
Можешь передавать в array переменную которая объявлена как int new_array[10][20], не обязательно ее делать VLA. Но если размер new_array определяется переменными, то его объявление будет таким int new_array[size1][size2].

А обработка ошибок в Go — это благодать. Многословность компенсируется необходимостью явно проверять ошибки и избавляет от усложнённого потока выполнения, когда при простом чтении не знаешь когда произойдёт обрыв.

Если код ответственно все проверяет, то он будет разростаться в несколько раз, за этими проверками не видно самого кода.

Есть схожая проблема у ручного управления памятью, невозможно писать элегантные функции как в функциональном программировании, даже хвостовая рекурсия ограниченна из за стадии очистки (в Golang тоже из за defer?).

Лучше взять пример с логикой или обработкой сущностей, но мне не хочется придумывать их сейчас, поэтому давай арифметику возьму, на ней тоже хорошо видно.

Вот был понятный код с исключениями, такой:

try {
  l = sqrt(pow2(x1 - x2) + pow2(y1 * y2))
} catch (BigNumberException e) {
  log write
  exit or return
}
Или такой:
try {
  a = pow2(sub(x1, x2))
  b = pow2(mul(y1, y2))
  c = sqrt(add(a, b))
} catch (BigNumberException e) {
  log write
  exit or return
}
Без исключений он превращается в:
r1 = x1 - x2
if r1 == error {
  log write
  exit or return
}

r2 = pow2(r1)
if r2 == error {
  log write
  exit or return
}

r3 = y1 * y2
if r3 == error {
  log write
  exit or return
}

r4 = pow2(r3)
if r4 == error {
  log write
  exit or return
}

r5 = r1 + r4
if r5 == error {
  log write
  exit or return
}

r6 = sqrt(r5)
if r6 == error {
  log write
  exit or return
}

Исправление MOPKOBKA, :

Ну да, специально смешиваю. Цель была показать сложность в работе с C.

У С просто возможностей большей. Если нужна скорость, то в Golang придется руками вычислять индексы.

Чтобы передать непрерывный массив, разве не так?

Ты наверное такой код хотел написать?

int print_array(int width, int height, int array[width][height])
Можешь передавать в array переменную которая объявлена как int new_array[10][20], не обязательно ее делать VLA. Но если размер new_array определяется переменными, то его объявление будет таким int new_array[size1][size2].

А обработка ошибок в Go — это благодать. Многословность компенсируется необходимостью явно проверять ошибки и избавляет от усложнённого потока выполнения, когда при простом чтении не знаешь когда произойдёт обрыв.

Если код ответственно все проверяет, то он будет разростаться в несколько раз, за этими проверками не видно самого кода.

Есть схожая проблема у ручного управления памятью, невозможно писать элегантные функции как в функциональном программировании, даже хвостовая рекурсия ограниченна из за стадии очистки (в Golang тоже из за defer?).

Лучше взять пример с логикой или обработкой сущностей, но мне не хочется придумывать их сейчас, поэтому давай арифметику возьму, на ней тоже хорошо видно.

Вот был понятный код с исключениями, такой:

try {
  l = sqrt(pow2(x1 - x2) + pow2(y1 * y2))
} catch (BigNumberException e) {
  log write
  exit or return
}
Или такой:
try {
  a = pow2(sub(x1, x2))
  b = pow2(mul(y1, y2))
  c = sqrt(add(a, b))
} catch (BigNumberException e) {
  log write
  exit or return
}
Без исключений он превращается в:
r1 = x1 - x2
if r1 == error {
  log write
  exit or return
}

r2 = pow2(r1)
if r2 == error {
  log write
  exit or return
}

r3 = y1 * y2
if r3 == error {
  log write
  exit or return
}

r4 = pow2(r3)
if r4 == error {
  log write
  exit or return
}

r5 = r1 + r4
if r5 == error {
  log write
  exit or return
}

r6 = sqrt(r5)
if r6 == error {
  log write
  exit or return
}

Исходная версия MOPKOBKA, :

Ну да, специально смешиваю. Цель была показать сложность в работе с C.

Если больше возможностей = большей сложностей, то видимо С сложнее.

Чтобы передать непрерывный массив, разве не так?

Ты наверное такой код хотел написать?

int print_array(int width, int height, int array[width][height])
Можешь передавать в array переменную которая объявлена как int new_array[10][20], не обязательно ее делать VLA. Но если размер new_array определяется переменными, то его объявление будет таким int new_array[size1][size2].

А обработка ошибок в Go — это благодать. Многословность компенсируется необходимостью явно проверять ошибки и избавляет от усложнённого потока выполнения, когда при простом чтении не знаешь когда произойдёт обрыв.

Если код ответственно все проверяет, то он будет разростаться в несколько раз, за этими проверками не видно самого кода.

Есть схожая проблема у ручного управления памятью, невозможно писать элегантные функции как в функциональном программировании, даже хвостовая рекурсия ограниченна из за стадии очистки (в Golang тоже из за defer?).

Лучше взять пример с логикой или обработкой сущностей, но мне не хочется придумывать их сейчас, поэтому давай арифметику возьму, на ней тоже хорошо видно.

Вот был понятный код с исключениями, такой:

try {
  l = sqrt(pow2(x1 - x2) + pow2(y1 * y2))
} catch (BigNumberException e) {
  log write
  exit or return
}
Или такой:
try {
  a = pow2(sub(x1, x2))
  b = pow2(mul(y1, y2))
  c = sqrt(add(a, b))
} catch (BigNumberException e) {
  log write
  exit or return
}
Без исключений он превращается в:
r1 = x1 - x2
if r1 == error {
  log write
  exit or return
}

r2 = pow2(r1)
if r2 == error {
  log write
  exit or return
}

r3 = y1 * y2
if r3 == error {
  log write
  exit or return
}

r4 = pow2(r3)
if r4 == error {
  log write
  exit or return
}

r5 = r1 + r4
if r5 == error {
  log write
  exit or return
}

r6 = sqrt(r5)
if r6 == error {
  log write
  exit or return
}