Форум программистов, компьютерный форум, киберфорум
CoderHuligan
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск  

Типизация функций - зло или добро?

Запись от CoderHuligan размещена 17.02.2023 в 13:47
Показов 9925 Комментарии 97

Это продолжение размышлений из позапрошлого поста данного блога.
На этот раз разговор пойдет о функциях.
Обычные языки программирования (ЯП) имеют не только типизированные наборы данных - структурный тип, но и как ни странно, это распространяется и на функции (процедуры). То есть: каждая отдельная функция представляет собой совершенно отдельный тип. Происходит это от того, что сигнатуры функций могут различаться, как по количеству формальных аргументов, так и по их типу, и по их порядку размещения. А так как это все не поддается никакой систематизации с точки зрения языка, и отдано на откуп программистам, то и получается, что сигнатура функции представляет собой отдельный "функциональный" тип.
Хорошо это или плохо я не знаю, вот и пытаюсь выяснить..
Плохо то, что порядок размещения, тип и количество аргументов накладывает дополнительную нагрузку на мозг программиста, так как все это надо помнить, а если и не помнить, то обращаться к докам, что замедляет процесс кодирования.
К тому же, вызывающая функция обязана знать эту сигнатуру, иначе вызов вызываемой функции становится невозможен. А это означает одно: большую связность кода, что приводит к проблемам переносимости, расширения, изменения и т.д.
Раньше, когда памяти было немного, такой подход был оправдан. Однако сейчас памяти у мас завались: её некуда девать, а производительность от этого не увеличилась, а продолжает падать..
Далее.
По соглашениям функция (к примеру в языке Си или С++) оставляет возвращаемое значение в регистре EAX. Так уж повелось и закрепилось. Однако для передачи аргументов используется стек в памяти. Иначе невозможно обеспечить рекурсивность, когда функция, к примеру, вызывает сама себя. Однако в обычных приложениях рекурсивные алгоритмы используются крайне редко, поэтому парадигма, которая заточена только на то, что кто-то когда-то может использовать рекурсию, становится достаточно накладной.

Допустим у функции есть два или три аргумента. Её вызывает другая функция. Эта другая знает, что вызываемая имеет три аргумента определенных типов. И вот, нам нужно изменить сигнатуру вызываемой: добавить четвертый аргумент. Добавили. При этом нам требуется изменить и код тех функций, которые вызывают данную, так как её сигнатура изменилась.. Это не просто плохо, а очень плохо, и считается дурным тоном. Но от этого никуда не деться. ООП прошу не предлагать.
То есть изменился тип функции, теперь он стал другим, и по цепочке это повлияло на все вызывающие функции.
Это плохо потому, что каждый программный компонент становится зависим от других, а ведь все мечтают о независимости модулей.. Оопщики это понимают, но нашли выход в другой, еще более развесистой лапше.
Как можно было бы выйти из данной ситуации? Вот два примера:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s1[20]="haha";
char s2[20]="hoho";
char * concat(char *c1, char *c2)
{
    int m, i;
  m=strlen(c1); i=0;
  while((*(c1+m+i) = *(c2+i)) !='\0')
    i++;
  return c1;
}
int main(void)
{
  printf("%s\n", concat(s1, s2));
  exit(0); 
}
Это пример традиционного подхода. Если сигнатура функции concat изменится, то код в main перестанет работать.
Вот пример другого подхода:
C
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
char s1[20]="haha";
char s2[20]="hoho";
typedef struct T
{
  char *c1;
  char *c2;
}T;
char * concatS(T *a)
{
    int m, i;
  m=strlen(a->c1); i=0;
  while((*(a->c1+m+i) = *(a->c2+i)) !='\0')
    i++;
  return a->c1;
}
 
int main(void)
{
  T d;
  d.c1=s1;
  d.c2=s2;
  printf("%s\n", concatS(&d));
  exit(0); 
}
Теперь, при изменении сигнатуры структурного типа T, например, путем добавления еще одного поля, код в main будет продолжать работать, сколько бы и каких бы функций мы не вызывали.
Что мы видим в последнем примере? Ну, то, что теперь мы имеем функцию с одной точкой входа в неё. Именно с одной! То есть функция возвращает одно значение и принимает одно значение, хотя фактически работает с двумя! Через единственный указатель..
Появляется сразу вопрос: а что мы можем с этого получить? новую парадигму? Может быть, а может быть и нет. Но, то, что это приносит свои плюшки - очевидно.
Если с одним структурным типом работает множество функций, то изменение этого типа, не приносит изменений этих других функций просто потому, что налицо наличие единственного типа сигнатуры функции, за исключением типа единственного аргумента. Но и это обстоятельство можно было бы преодолеть.. А как это уже другой вопрос..
Размещено в Без категории
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Всего комментариев 97
Комментарии
  1. Старый комментарий
    Опять же.... если используете чужую либу - вы понимаете зачем ее используете. Ну и контролируйте ченжлог.... если там вышли не адекватные изменения - значит оставляете в зависимостях старую версию.
    Запись от voral размещена 20.02.2023 в 12:32 voral вне форума
  2. Старый комментарий
    Иначе можно совсем до маразма найти. И завтра давайте подумаем: а если завтра Вася Пупкин в коде на C++ захочет писать русскими словами команды..... Будете правки в компилятор C++ вносить или же попросту пошлете его с его хотелками?
    Запись от voral размещена 20.02.2023 в 12:34 voral вне форума
  3. Старый комментарий
    Аватар для XLAT
    Цитата Сообщение от CoderHuligan
    а предположим, что код пишется командами, одна из которых ничего не знает о модулях другой, но вынуждена пользоваться общей библиотекой? Или интерфейсом модуля другой команды? Шило в одном месте.
    офигеть проблема у вас:
    в С++ это разрулили ещё 30 лет назад.
    гуглите "области видимости и пространства имен в С++"
    Запись от XLAT размещена 20.02.2023 в 13:18 XLAT вне форума
  4. Старый комментарий
    Аватар для CoderHuligan
    Да причем здесь пространство имен?? Речь не об этом. Вот два кода:
    1)
    Code
    1
    2
    3
    4
    
    func1(){
      func2(a, b, c)
      func3(c, b, a, g)
    }
    и
    2)
    Code
    1
    2
    3
    4
    
    func1{
      func2// a b c лежат на стеке
      func3// тоже
    }
    Какой код чище? А где аргументы? В последнем случае важно только имя функции. Сигнатура каждой функции скрыта от внешнего мира (сокрытие данных). В самом коде, во время вызова, это не прописывается. Это прописано только в определении функции. Или в обьявлении. Налицо ограничение. Если вместо трех параметров функции надо передать всего одно, то статические языки этого не позволят. Динамические позволят, да и то не все.
    Современные языки мало чего позволяют. К примеру нельзя прыгнуть прямо внутрь выражения. Это невозможно. Но если это реализовать, то появилось бы больше возможностей для самовыражения. Так и по другим пунктам.
    Запись от CoderHuligan размещена 20.02.2023 в 15:17 CoderHuligan вне форума
  5. Старый комментарий
    Цитата Сообщение от CoderHuligan
    Какой код чище? А где аргументы?
    1 первый чище. т.к. гарантированно нет сайдэффектов, и гарантировано есть параметры необходимые для выполнения функции
    2 судя из приведенного примера вам просто надо все переменные хранить в глобальной области видимости.... Надо ли это кому то еще кроме вас ?
    3 читая 1 код я точно знаю что этой функции нужны конкретные переменные, во втором случае я спокойно выкину переменную, которая, как мне вдруг покажется, не нужна.

    Таким образом тут дело не только в чистоте (но я по прежнему считаю первый более чистым), но и в меньше шансов получить баги сложно выявляемые.

    Цитата Сообщение от CoderHuligan
    В последнем случае важно только имя функции. Сигнатура каждой функции скрыта от внешнего мира (сокрытие данных).
    И чем это хорошо? т.е. публичная функция параметры которой являются секретом - ни каких несостыковок не замечаете?
    Более того, передачу по значению и по параметру -придумали не просто так. При этом если чайник создаст функцию по тому принципу как сейчас есть (в случае простых типов параметров), она не будет иметь сайдэффекта (по крайней мере в отношении этих параметров), а вот в вашем случае будет если он не предпримет некоторые действия. Если же вы имеете ввиду стек вызываемой функции - тогда опять же вы ни чего нового не предлагаете. т.к. во втором примере вы не показали как вы эти переменные в стек положили (хотя, судя по комментарию речь все же о глобальных переменных).. При этом глбальные переменные на столько глобальные, что они даже между модулями глобальные.... А это вообще трындец проекту. тут уже рассуждать о "сайдэффектах" нет смысла - код будет жить своей жизнью.

    И вот вам еще и 4 пункт... в вашей второй версии, мы, используя эту функцию, и не имея представления что там внутри, должны будем на всякий случай, сами делать копию перменной. (возьмите ваши примеры, и подумайте что будет если вам важно, чтоб переменные в области видимости func1 не меняли значения. те.. передавались именно по значению. Вы уверены что внутри func2 нет a= a +100500 ?


    Цитата Сообщение от CoderHuligan
    Если вместо трех параметров функции надо передать всего одно, то статические языки этого не позволят. Динамические позволят, да и то не все.
    И что за функция где это нужно? И чем отсутствие одного из параметра, отличается от его необязательности и наличием возможности задать значение по умолчанию? Странная ситуация, вы не приводите конкретный пример. Вы сразу говорите "это важно и надо"... зачем? почему? кому?


    Цитата Сообщение от CoderHuligan
    Но если это реализовать, то появилось бы больше возможностей для самовыражения.
    Нет. Программирование это не рисование где провел линию по другому и можно сказать "я художник я так вижу"... Ваша хотелка, если ее реализовать, приведет к сложно тестируемому коду, который будет сложно читать. А уж баги в нем искать...... Тут не самовыражаться надо, а максимально четко излагать свои мысли.

    А все крутится вокруг чисто академического интереса, а не реальной ситуации с реальным проектом. Как и с обсуждением goto. К слову, я пожалуй впервые за 23 года (раньше не помню, возможно даже впервые за 33-36 лет применил goto. Да и то потому что между меткой и goto гарантировано не будет расти код, и я единственный разработчик.
    Запись от voral размещена 20.02.2023 в 16:03 voral вне форума
  6. Старый комментарий
    Проиллюстрирую ваш код для случая, что нам важно чтобы функция не меняла входные параметры
    Code
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    
    func1{
      tmpA = a
      tmpB = b
      tmpC = c
      tmpG = g
      // и так все переменные в нашей программе,
      // т.к.  мы же не знаем что функция захочет использовать
      func2// a b c лежат на стеке
      a = tmpA
      b = tmpB
      c = tmpC
      g = tmpG
      func3// тоже
      a = tmpA
      b = tmpB
      c = tmpC
      g = tmpG
    }
    А "классический" будет гораздо чище. даже если пред положить, что функция работает "по ссылке", тогда мы "сохраним" только те переменные, которые передавали, а не все....
    Запись от voral размещена 20.02.2023 в 16:13 voral вне форума
  7. Старый комментарий
    Ну и плюсом... Что значит "лежат на стеке"? В стеке их функции разбирают "по порядку" или "по имени"? Как вообще вы видите помещение этих переменных в этот стек?
    Запись от voral размещена 20.02.2023 в 16:15 voral вне форума
  8. Старый комментарий
    Аватар для CoderHuligan
    Программирование это не рисование где провел линию по другому и можно сказать "я художник я так вижу"... Ваша хотелка, если ее реализовать, приведет к сложно тестируемому коду, который будет сложно читать. А уж баги в нем искать......
    Поймите же наконец одну вещь: нельзя всех построить в одну шеренгу и начать отдавать команды типа упал/отжался.. Ну не все хотят строем идти, многие ностальгируют по turbo basic, причем до сих пор. По простым осям, языкам. По языкам, в которых - да, можно отстрелить себе ногу, но это будет ваша нога, а опыт приобретается в боях, а не в комфортной среде языков, где вам этого сделать не позволят. Современные языки, заточенные на продакшен зачастую не есть то, что нужно любителям. Мне интересно искать баги в собственном коде и разбираться в низкоуровневых конструкциях. Интересно использовать простые решения, простые IDE, языки. То есть те инструменты которые я могу понять. Если я не могу понять инструмент, то он не мой. Как школьнику объяснить каким образом инфиксное выражение превращается в целевой код? Для этого школьнику надо сперва прочесть книгу дракона (Ахо, Ульман, Компиляторы и их реализация) книжку на 1000 стр. Затем какой-нибудь ассемблер и еще кучу разной литературы. Между тем постфиксное выражение можно объяснить на пальцах одной руки, так как оно не требует преобразования и не требует знания работы YACC/LEX. То есть: меняем всего один параметр, и сразу отпадает куча слоев, и все становится проще и яснее. В инфиксное выражение прыгнуть естественно нельзя, а постфиксное - можно. Профи фыркнут как обычно, а ценители заценят.
    И что за функция где это нужно? И чем отсутствие одного из параметра, отличается от его необязательности и наличием возможности задать значение по умолчанию? Странная ситуация, вы не приводите конкретный пример. Вы сразу говорите "это важно и надо"... зачем? почему? кому?
    Разработчику это надо. Ему важно иметь возможность работать только с одной сущностью. Допустим одна функция производит деление двух аргументов и на выходе возвращает два значения а) частное б) остаток.
    Другая функция берет два аргумента и делает с ними что-то еще. Допустим в процессе нам потребовалось, что вторая функция еще принимала бы третий аргумент - погрешность. В этом случае придется изменить код всех функций в которых прописан вызов данной. Это не есть хорошо. Между тем, если бы была скрыта явная передача фактических параметров, то изменение кода произошло бы только в данной функции.
    Почему аргументы мы передаем через стек, а возвращаемое значение оставляем в низкоуровневом регистре EAX? Это сразу привязывает нас к определенной жестко заданной системе. Если же возвращаемые значения также оставлять в стеке, то можно возвращать любое их количество.
    Можно возразить: тогда трудно было бы контролировать стек. Но это можно автоматизировать.
    Запись от CoderHuligan размещена 20.02.2023 в 16:39 CoderHuligan вне форума
  9. Старый комментарий
    Аватар для Usaga
    Однако для передачи аргументов используется стек в памяти.
    Не обязательно. Есть же _fastcall вариант. Но и ещё один момент, который ниже.

    И вот, нам нужно изменить сигнатуру вызываемой: добавить четвертый аргумент. Добавили.
    А можно передавать один аргумент, структурой\классом.

    Если с одним структурным типом работает множество функций,
    То мы получаем раздутую и избыточную структуру, а так же полную неопределённость, ибо мы уже не знаем какие из её полей нужны данной функции, а какие нет. Получаем лапшу, кашу которую вы "ООПэшникам" приписываете.

    Плохо то, что порядок размещения, тип и количество аргументов накладывает дополнительную нагрузку на мозг программиста, так как все это надо помнить, а если и не помнить, то обращаться к докам, что замедляет процесс кодирования.
    К каким докам? Можно просто на сигнатуру функции посмотреть прямо в IDE...
    Запись от Usaga размещена 20.02.2023 в 16:43 Usaga вне форума
  10. Старый комментарий
    Аватар для CoderHuligan
    ----
    Запись от CoderHuligan размещена 20.02.2023 в 16:54 CoderHuligan вне форума
  11. Старый комментарий
    Аватар для Usaga
    ----
    Запись от Usaga размещена 20.02.2023 в 17:40 Usaga вне форума
  12. Старый комментарий
    Цитата Сообщение от CoderHuligan
    Поймите же наконец одну вещь: нельзя всех построить в одну шеренгу и начать отдавать команды типа упал/отжался..
    Вы некорректно проводите параллели. Если ребенок хочет прыгнуть с крыши чтоб полетать. А родитель говорит что так нельзя. Это тоже считаете что ребенка "в одну шеренгу и начать отдавать команды типа упал/отжался.."?

    Цитата Сообщение от CoderHuligan
    Как школьнику объяснить каким образом инфиксное выражение превращается в целевой код?
    А почему вы приводите отстраненный пример? вы уж берите и сравниваейте, что легче объяснить:
    1. вот функция у нее есть аргументы они такие
    2 вот функция ты там ее вызови, но сначала глянь в доке чего она хочет и загони куда то вот туда эти переменные.....

    Цитата Сообщение от CoderHuligan
    Для этого школьнику надо сперва прочесть книгу дракона (Ахо, Ульман, Компиляторы и их реализация) книжку на 1000 стр. Затем какой-нибудь ассемблер и еще кучу разной литературы.
    Вот в вашем варианте так и получится в итоге.


    Цитата Сообщение от CoderHuligan
    Разработчику это надо. Ему важно иметь возможность работать только с одной сущностью. Допустим одна функция производит деление двух аргументов и на выходе возвращает два значения а) частное б) остаток.
    Другая функция берет два аргумента и делает с ними что-то еще.
    Да ситуация частая - поэтому в проекте создаются обертки, которые коррелерируют с предметной областью и гоняйте именно стркутуру/объект.

    Цитата Сообщение от CoderHuligan
    Допустим в процессе нам потребовалось, что вторая функция еще принимала бы третий аргумент - погрешность. В этом случае придется изменить код всех функций в которых прописан вызов данной.
    Это не так. Пути как я описал выше два:
    1. Значение по умолчанию
    2. Другая похожая на первую функция, но с погрешностью

    Если для проекта важно: все равно надо будет править места вызова. И в случае вашего стека тоже.


    Цитата Сообщение от CoderHuligan
    Если же возвращаемые значения также оставлять в стеке, то можно возвращать любое их количество.
    Т.е. вся система разом становится не стабильной.
    Но вы так и не пояснили: а как будет конкретная функция доставать из этого стека то, что ей нужно. "Стек" в классическом понимании тут явно не подойдет. По именам тоже не проктит (и придется с чужими либами как то сопрягаться, и вообще с переменными не разбериха будет Например у меня есть в стеке два числа a и b . я пишу код на вашем языке
    a= 2 b =4
    Code
    1
    2
    3
    4
    5
    
    // тут некая реализация помещения в стек
    sqr
    sqr
    sum
    print
    Что в результате выполнения будет?
    Запись от voral размещена 20.02.2023 в 19:01 voral вне форума
  13. Старый комментарий
    Аватар для Usaga
    Да ситуация частая - поэтому в проекте создаются обертки, которые коррелерируют с предметной областью и гоняйте именно стркутуру/объект
    Но это же шаг в сторону богомерзкого ООП! А ТС порицает и отвергает то, что не понимает.
    Запись от Usaga размещена 21.02.2023 в 00:55 Usaga вне форума
  14. Старый комментарий
    Аватар для CoderHuligan
    Цитата Сообщение от voral
    Но вы так и не пояснили: а как будет конкретная функция доставать из этого стека то, что ей нужно. "Стек" в классическом понимании тут явно не подойдет. По именам тоже не проктит (и придется с чужими либами как то сопрягаться, и вообще с переменными не разбериха будет Например у меня есть в стеке два числа a и b . я пишу код на вашем языке
    a= 2 b =4
    Что в результате выполнения будет?
    Да, вы правы, стек тут не прокатит.. Зато очередь может. Допустим код заталкивает в очередь a= 2 b =4. Очередь выглядит так:
    а в
    А sqrt извлекает корень из 4 и толкает результат в очередь, которая теперь выглядит так:
    рез 2
    Следующий sqrt извлекает корень из 2 и толкает результат в очередь:
    рез рез
    Получившийся код:
    а в sqrt sqrt
    С другой стороны, если бы у нас был стек, то код был бы таким:
    а в sqrt SWAP sqrt
    swap берет два верхних значения и меняет их местами. Налицо полная зависимость от стека. С очередью все намного проще и естественней выходит. Причем очередь позволяет делать задержку выполнения, что не позволяет стек. Это более высокоуровневая структура данных чем стек, так как имеет вместо одного входа, один вход и один выход (почти элемент И/НЕ).
    То есть видим: многое зависит от реализации низкоуровневых механизмов, которые отражаются на верхних уровнях.
    Запись от CoderHuligan размещена 21.02.2023 в 12:06 CoderHuligan вне форума
  15. Старый комментарий
    Аватар для CoderHuligan
    К сожалению очередь также не тянет на универсальный интерфейс..
    Запись от CoderHuligan размещена 21.02.2023 в 16:11 CoderHuligan вне форума
  16. Старый комментарий
    Цитата Сообщение от CoderHuligan
    Да, вы правы, стек тут не прокатит.. Зато очередь может. Допустим код заталкивает в очередь a= 2 b =4. Очередь выглядит так:
    а в
    А sqrt извлекает корень из 4 и толкает результат в очередь, которая теперь выглядит так:
    рез 2
    Следующий sqrt извлекает корень из 2 и толкает результат в очередь:
    рез рез
    таким образом все становится очень зависимым от очередности и от делает ли функция что то или нет. И сразу мой код на вашем языке становится абсолютно не читаемым. Стоит между двумя sqr добавить еще функцию и все разваливается. Не говоря о том, что вы не угадали, то что я хотел сделать

    А так же и код ваш где то в начале обсуждения становится нерабочим. Точнее это лотеря - может повезет а может нет. Если переменные в очреди останутся в нужном порядке - повезло. Если учесть что вы ратуете еще и за "прыжки" по коду, то код становится абсолютно не отлаживаемым.


    Цитата Сообщение от CoderHuligan
    То есть видим: многое зависит от реализации низкоуровневых механизмов, которые отражаются на верхних уровнях.
    Нет. Тут мы видим, что тут сложность вырастает многократно. Мало того что мы будем обязаны знать как реализована каждая функция внутри, но и перед вызовом каждой обеспечивать правильно состояние очереди.
    Запись от voral размещена 21.02.2023 в 16:28 voral вне форума
  17. Старый комментарий
    Цитата Сообщение от CoderHuligan
    которые отражаются на верхних уровнях.
    Что является самым хреновым вариантом сайдэффекта.
    Запись от voral размещена 21.02.2023 в 16:29 voral вне форума
  18. Старый комментарий
    Аватар для CoderHuligan
    ---
    Запись от CoderHuligan размещена 22.02.2023 в 11:18 CoderHuligan вне форума
  19. Старый комментарий
    Аватар для XLAT
    Цитата Сообщение от CoderHuligan
    Вот пример, где очередь вместо стека может упростить понимание постфиксных выражений..
    хулиган, хорош херней маяться,
    давай лучше вместе Морской Бой сделаем по сети на онлайн с 10'000 игроками.

    я перебираю задачи которые реально для профита нужно порешать
    я не вижу в них ни одной той фигни, про которые ты тут пишешь.
    Запись от XLAT размещена 22.02.2023 в 11:21 XLAT вне форума
  20. Старый комментарий
    Аватар для CoderHuligan
    хулиган, хорош херней маяться,
    Я удалил, потому что это действительно ерунда полная.
    давай лучше вместе Морской Бой сделаем по сети на онлайн с 10'000 игроками.
    В качестве лабораторной работы для собственного опыта - можно было бы запилить. Тем более что заготовка есть, правда на си и только под одного игрока. С сетью я не работал, хотя есть примеры кода как это делается.
    Если и буду делать, то только на Tcl Tk, тем более там очень легко работать с сокетами и делать полноценное гуи. Коммерция меня не интересует.
    Запись от CoderHuligan размещена 22.02.2023 в 11:48 CoderHuligan вне форума
 
Новые блоги и статьи
Hyper-V: Компьютер должен поддерживать доверенный платформенный модуль 2.0.
Maks 31.08.2026
При установке Windows 11 на виртуальную машину Hyper-V 2-го поколения вылезла такая ошибка: Решение: в параметрах виртуальной машины, в разделе "Безопасность" (Security) активировать флаг. . .
Архитектура биовида Стива в Майнкрафте: Зачем бонобо кубический каннибализм
anaschu 30.08.2026
Кубический Вагинокапитализм в Minecraft: Математический инвариант ОДУ и рок Стивов-бонобо Главная задача разработанной «Модели Всего» — наглядно продемонстрировать наличие системной «судьбы». . .
Оттачиваю умение писать js программы.
russiannick 30.08.2026
Проектом выходного дня стало написание Книги шифров Виженера. Итогом стала версия 200, синий туман. Синий туман назван так, потому что замораживает текст под собой. Нажатие синих кнопок управляют. . .
мат медиц модель 30. презентация проекта
anaschu 27.08.2026
хоп хоп хоп хидахоп, а я кладую))
Как у меня протекала болезнь
zorxor 27.08.2026
Здравствуйте, друзья! Эта запись блога предназначена именно для вас - для моих дорогих друзей, которые знали меня лично. Чтобы ответить на вопрос - а что же со мной произошло на самом деле? Я учился. . .
Нашел вот забавное видео о измерениях. Лучшее что я видел на эту тему
kumehtar 26.08.2026
ILETXiw9bMQ Основная суть и тезисы по измерениям: 0D (Нулевое измерение): точка, не имеющая длины, ширины, высоты или объема. Объект не может перемещаться в 0D. 1D (Первое измерение):. . .
[EasyBuilder Pro] Памятка по разработке для панелей Weintek
ФедосеевПавел 26.08.2026
Памятка по разработке для панелей Weintek ВВЕДЕНИЕ Ранее, при реализации проектов основное внимание уделял разработке управляющей программы для контроллера, а панели оператора доставалось время. . .
Модель по догадкам
anaschu 25.08.2026
Прошло две недели. Я уже рассказывал, как разговаривал с сотрудниками у сортировки и как понял, что главная ветка — не про приёмку, а про отбор. Но тогда я думал, что понял механику. На этой неделе я. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru