LINUX.ORG.RU
Ответ на: комментарий от yyk

«В оптических системах могут производиться операции умножения вектора на матрицу, вычисление корреляционных функций, выполняться преобразование Фурье и другие операции.»

Как тебе Фурье за 1 такт? Разве плохо?

Liz812
()
Ответ на: комментарий от SZT

Бред полный при чем тут это? При наличие в языке static и глобальных переменных про ссылочную прозрачность и идемпотеность сразу можно забыть.

Liz812
()
Ответ на: комментарий от Liz812

Бред полный при чем тут это?

А что ты тогда хочешь увидеть?

При наличие в языке static и глобальных переменных про ссылочную прозрачность и идемпотеность сразу можно забыть.

Ну так не используй никаких static и глобальных переменных

SZT ★★★★★
()
Ответ на: комментарий от Legioner

Если объяснишь, что это такое, объясню, как на С реализовать.

Ты должен выполнить контракт с компилятором. Что он твои функции в целях оптимизации может вызывать в произвольном порядке и произвольных тредах, параллельно или последовательно решает он сам. Да еще, циклы использовать нельзя, у тебя их нет.

Liz812
()
Ответ на: комментарий от Liz812

Что он твои функции в целях оптимизации может вызывать в произвольном порядке и произвольных тредах, параллельно или последовательно решает он сам.

Что-то похожее есть в атрибутах к функциям в GCC https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html

const

Calls to functions whose return value is not affected by changes to the observable state of the program and that have no observable effects on such state other than to return a value may lend themselves to optimizations such as common subexpression elimination. Declaring such functions with the const attribute allows GCC to avoid emitting some calls in repeated invocations of the function with the same argument values.

For example,

int square (int) __attribute__ ((const));

tells GCC that subsequent calls to function square with the same argument value can be replaced by the result of the first call regardless of the statements in between.

SZT ★★★★★
()
Ответ на: комментарий от SZT

Ты ещё про Тезис Черча [s]ей[/s]ему расскажи. Утонченное наслаждение: кормить на ЛОРе явного тролля.

anonymous
()
Ответ на: комментарий от Liz812
$ cat fact.c
#include <stdio.h>
int fact_helper(n, a) {
  if (n == 0) {
    return a;
  } else {
    return fact_helper(n-1, n*a);
  }
}
int fact(int n) {
  return fact_helper(n, 1);
}
int main() {
  printf("Int(10000!) = %d\n", fact(10000));
  return 0;
}
MigMit:~ migmit$ ./fact
Int(10000!) = 0

Можно, конечно, и непереполняющуюся арифметику реализовать, но надо ли?

Miguel ★★★★★
()
Ответ на: комментарий от Liz812

И почему у тебя стек не переполняется?

А ты слышала что-нибудь про tail-call optimization? Почитай, думаю пригодится.

SZT ★★★★★
()
Ответ на: комментарий от Liz812

Ошибка, но на самом деле нет. Старый синтаксис C позволяет так писать.

Miguel ★★★★★
()
Ответ на: комментарий от Liz812

Не сказано, но нормальные люди делают. Собственно, если не ошибаюсь, стандарт Haskell 98 тоже про неё не говорит.

Miguel ★★★★★
()
Ответ на: комментарий от Miguel

Лучше как-нибудь так:

unsigned int fact( unsigned int n) { return n < 1 ? 1 : n*fact(n-1); }

Можно конечно свои бигинты накостылить, но мне лень

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от SZT

А если inline добавить, то вообще никаких вызовов не останется, будет чисто умножение в цикле. И gcc, и clang.

anonymous
()
Ответ на: комментарий от SZT

Хех. Не переполняется (даже с -O0), потому что 10000 — это очень мало. Стека банально хватает.

Miguel ★★★★★
()
Ответ на: комментарий от fsb4000

Иммутабельные данные это тормоза на копирование

А мутабельные — на отладку. И да, полностью копировать не обязательно же.

Nervous ★★★★★
()
Ответ на: комментарий от Liz812

Но зачем? У компилятора языка C нет такого контракта. Ты хочешь придумать какое-то подмножество C? Ну ради бога, передавай всё через параметры функций. Вместо циклов используй рекурсию.

Legioner ★★★★★
()
Ответ на: комментарий от SZT

Хороший мальчик. А теперь давай покажи редьюсер. Только без циклов, чисто на рекурсии. Можно даже не ленивый, простой такой редьюсер.

Liz812
()
Ответ на: комментарий от SZT

Вообще-то, да, пора либо аргументы предъявлять, либо дензнаки.

Miguel ★★★★★
()
Ответ на: комментарий от SZT

И еще наверно вызовы libc надо в монадку заворачивать? А иначе вся функциональная чистота сразу нафиг. Давайте мальчики, веселье только начинается.

Liz812
()
Ответ на: комментарий от Liz812

Ахах, хватит уже, не смеши меня.

По поводу «libc в монадку» - в libc вполне есть фунции, которые никаких сайд-эффектов не имеют. Синусы-косинусы например. Так что не все вызовы libc в монадку надо заворачивать. Впрочем, как и в каком-нибудь хаскеле, там далеко не все функции в монадках.

Ну и заниматься реализацией всякой функциональной фигни в Си просто так я не буду. У меня есть дела поважнее.

SZT ★★★★★
()
Ответ на: комментарий от anonymous

Я хз если честно, прогуляла, а гуглить лень :)) Знаю что еще есть трансдьюсеры это еще одна мегапримочка из мира функцинальных языков.

Liz812
()
Ответ на: комментарий от Liz812

Ну кстати я так и подумал, у тебя там наверно домашка что надо редьюсер на Си написать, вот ты и решила так схитрить

SZT ★★★★★
()
Ответ на: комментарий от SZT

надо редьюсер на Си написать

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

anonymous
()
Ответ на: комментарий от Liz812

Не обманывай нас!

Похоже ты просто путаешь операцию свёртки с мифическим «редьюсером», что ты подразумеваешь под «трансдьюсером» я вообще страшусь представить.

anonymous
()
Ответ на: комментарий от yyk

Что до определения - ну на тебе его из той самой лекции:

:) Что такое архитектура фон Неймана не знаешь.

доступно и массово в низкоуровневом кодинге можно не использовать «языки модели фон Неймана»?

То, что ты на «языке модели фон Неймана» настраиваешь DMA-контроллер, (кольцевые) буферы всяких разных карт для ускорения графики, звука, видео и вешаешься на прерывания - это не про модель фон-неймана. Для этого подойдет любой язык, умеющий генерить машинный код.

Когда-то напрямую читали-писали порты ввода-вывода (или замапленные блоки памяти). Вот это более-менее фон-Нейман. Давай, показывай свою скорость 3d-графики, прорисовывая сцены на ЦПУ. Показывай скорость чтения/записи на диски через PIO (prorgammed i/o). И смотри, чтобы курсор мышки не подвисал, когда записываешь на сбойную дискету 1.44.

Вот где мощь и скорость фон-Неймана.

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

anonymous
()
Ответ на: комментарий от Liz812

А это разве я сказала, что на С можно писать как на функциональном языке?

Я так тоже не говорил. Но вообще следует точно разобраться. Что именно ты понимаешь под «на С можно писать как на функциональном языке»? Например, считаешь ли ты, что возможен некоторый код на функциональном языке, который нельзя какими-либо методами оттранслировать в код на Си, делающий то же самое?

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от anonymous

Не. Вот:

A reducer is the combination of a reducible collection (a collection that knows how to reduce itself) with a reducing function (the «recipe» for what needs to be done during the reduction). The standard sequence operations are replaced with new versions that do not perform the operation but merely transform the reducing function. Execution of the operations is deferred until the final reduction is performed. This removes the intermediate results and lazy evaluation seen with sequences.

Transducers are composable algorithmic transformations. They are independent from the context of their input and output sources and specify only the essence of the transformation in terms of an individual element. Because transducers are decoupled from input or output sources, they can be used in many different processes - collections, streams, channels, observables, etc. Transducers compose directly, without awareness of input or creation of intermediate aggregates.

Liz812
()
Ответ на: комментарий от Liz812

А в чём проблема?

#include <stdio.h>

typedef int (*reduce_function)(int x, int y);

int reduce(reduce_function f, int z, int *xs, int *xe)
{
    return xs == xe ? z : reduce(f, f(z, *xs), xs + 1, xe);
}

int r(int x, int y)
{
    return x * 2 + y;
}

int main()
{
    int xs[] = {1, 2, 3};
    int v = reduce(r, 4, xs, xs + 3);
    printf("%d\n", v);
    return 0;
}
Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)

уровнем абстракции

anonymous
()
Ответ на: комментарий от Liz812

Муть какая-то. Засунь в структуру коллекцию и указатель на функцию и всё.

Legioner ★★★★★
()
Ответ на: комментарий от Liz812

Функция возвращающая новую функцию. Это каррирование.

Каррирование это частный случай. Комбинирование функций - ну это запросто. Например вот https://wandbox.org/permlink/F7VuPNrJOSrQanCk

Каррирование тоже можно такими костылями организовать

SZT ★★★★★
()
Последнее исправление: SZT (всего исправлений: 1)
Ответ на: комментарий от Liz812

Тебе надо передавать пару (функция, контекст) вместо просто функции. Как, собственно, все языки и делают «под капотом».

Legioner ★★★★★
()
Последнее исправление: Legioner (всего исправлений: 1)
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.