LINUX.ORG.RU

Сколько зарабатывает Pascal программист?

 , , ,


6

6

Здравствуйте. Я хочу узнать сколько можно заработать в 2022 году, зная Object Pascal и почему он не стал мейнстримным языком программирования. Почему он только изучается в школах и почему именно Pascal

Ответ на: комментарий от soomrack

В Си переменная получила тип при рождении и он всегда с ней, ты точно знаешь, что она именно этого типа, всегда, до самой смерти.

var = 1;
var = '1';

Это и в Си компилируется и даже без предупреждений.

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

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

В Питоне можно. Ставь type hint и зафиксируешь.

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

Слушай, для языка без указателей, понимать, что такое ссылка, чтобы понять как сработает код, это как-то странно.

Это тупо логика: есть переменная, я вызываю функцию в которой указываю ее. В функции эту переменную я меняю (инкремент или изменение первого элемента списка), и для int ее значение вне фукнции не меняется, а для списка – меняется. Ну как так то?!

...
do_it(var)
...
do_it(var)
...

и вот как понять, в какая из этих функций изменит переменную? в зависимости от того, что написано в … могут быть любые комбинации.

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

то уж «var += 1» для меня выглядит, как работа со старой

Так неважно работа со старой или новой. Внутрь функции в питоне передаётся не переменная, а ссылка на значение переменной. Та var, которая снаружи функции, никак изменена быть не может.

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

Это и в Си компилируется и даже без предупреждений.

Так тип переменной же не меняется, ты оба раза присваивает целое значение.

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

Ставь type hint и зафиксируешь.

Дай пример кода, где тип переменной не изменить.

PS: я на питоне большие проекты не делаю, поэтому не особо в курсе best practices.

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

Так тип переменной же не меняется, ты оба раза присваивает целое значение.

Так в питоне все переменные тоже фактически содержат целые числа.

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

Так неважно работа со старой или новой. Внутрь функции в питоне передаётся не переменная, а ссылка на значение переменной. Та var, которая снаружи функции, никак изменена быть не может.

А содержимое списка снаружи меняется, если его внутри функции изменить. Получается, что список это не цельная переменная, а ссылка + данные… А ссылок в питоне нет… Получается, что нужно рассказывать про ссылки, а их нет! Ну странно же.

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

На питоне ооп более внятное чем на плюсах вообще то.

А чо сразу плюсы? Лучше C без плюсов, чтобы питон засиял особенно ярко на его фоне. Хотя и плюсовое ООП не так убого как питонячье. Насчет ФП, его в питоне следовые количества, даже смешно об этом говорить. Более подчеркнуто императивный ЯП ещё поискать.

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

Дай пример кода, где тип переменной не изменить.

var: Int = 1
var = '1'
var = [1]
$ mypy test.py
test.py:2: error: Incompatible types in assignment (expression has type "str", variable has type "int")  [assignment]
test.py:3: error: Incompatible types in assignment (expression has type "List[int]", variable has type "int")  [assignment]
Found 2 errors in 1 file (checked 1 source file)
monk ★★★★★
()
Ответ на: комментарий от soomrack

А содержимое списка снаружи меняется

Именно. Если бы у целого числа было содержимое, его тоже можно было бы менять. И наоборот, если какая-то структура неизменяемая, то она снаружи не меняется

def print_tup(var: list):
    var += (2, )
    print(var)


def main():
    var = (0, 1)
    print_tup(var)
    print(var)

main()
(0, 1, 2)
(0, 1)

Не будешь же ты утверждать, что кортежи передаются по значению.

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

Более подчеркнуто императивный ЯП ещё поискать.

Функцию аргументом передать можно, compose есть. Ну и всякие reduce(operator.concat, ['A', 'BB', 'C'])

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

и вот как понять, в какая из этих функций изменит переменную? в зависимости от того, что написано в … могут быть любые комбинации.

Переменную – никакая. Она продолжит указывать на тот же самый объект. Содержимое объекта, на который указывает переменная (если объект изменяемый) – любая.

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

Так я то понимаю почему и как, я говорю про странность логики в синтаксисе языка. И необходимость думать что и как, вместо того, чтобы в явном виде указать когда изменения будут, а когда – нет.

Все эти языки без ссылок позиционируют их отсутствие как достоинство в плане безопасности и в плане ясности кода. И когда говорят, что переменная это список, то не говорят, что это ссылка+данные, нету такого разделения, это единая переменная и точка. А по факту получается, что это разделение не только есть, но и его необходимо понимать, чтобы понять что с переменной произойдет, когда ты ее в функцию закинешь.

А с т.з. обучения это приводит к двум вариантам, или как раньше рассказать про указатели, организацию памяти, и из них вывести что и как работает в питоне, или рассказывать сразу следствия не давая базу, но их много, и их логика странная, если про указатели не знать…

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

Так я то понимаю почему и как, я говорю про странность логики в синтаксисе языка. И необходимость думать что и как, вместо того, чтобы в явном виде указать когда изменения будут, а когда – нет.

Это не странность. Это как раз единственная разумная логика. В переменной хранится ссылка на некий объект. Если значение переменной передаётся в функцию, значит в функции есть ссылка к этому объекту. Но передаётся именно значение, а не сама переменная. Так было с 1958 года когда придумали лисп.

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

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

Это типизация в питоне. Ставится через pip install mypy или (у меня) apt install mypy.

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

Так, стоп. Ты передаешь целое число и оно передается как копия.

Нет. Слушайте, ну сколько можно…

>>> help(id)

Help on built-in function id in module builtins:

id(obj, /)
    Return the identity of an object.
    
    This is guaranteed to be unique among simultaneously existing objects.
    (CPython uses the object's memory address.)

def f(x):
    print(x, id(x))
    x *= 2
    print(x, id(x))

a = 1
f(a)
print(a, id(a))

b = [1]
f(b)
print(b, id(b))
$ python3 test.py 
1 140566949806320
2 140566949806352
1 140566949806320
[1] 140566948618816
[1, 1] 140566948618816
[1, 1] 140566948618816
AntonI ★★★★★
()
Ответ на: комментарий от monk

Переменную – никакая. Она продолжит указывать на тот же самый объект. Содержимое объекта, на который указывает переменная (если объект изменяемый) – любая.

т.е. переменная не хранит значение, а хранит указатель на значение? Ну и как тут понимать «var += 1».

C++: Привет ребята, «int age;» это объявление переменной, в нее мы можем записать целое число «age = 3;», а потом можем ее увеличить «age += 1;».

Python: Привет ребята, «age = 1» это объявление переменной и она указывает на объект где хранится число 1 (объект, о боже! что это? что это такое?), мы не можем увеличить значение переменной, а «age += 1» изменит значение объекта, т.е. то, на что она указывает.

А теперь, давайте напишем функцию, которая будет получать эту переменную на вход и менять ее значения на ваш возраст.

C++: void my_age(int &age) { age = 12 }; Значек «&» здесь означает, что функция будет работать с переменной, которую вы передали, а не с копией.

Python: никак.

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

А с т.з. обучения это приводит к двум вариантам, или как раньше рассказать про указатели, организацию памяти, и из них вывести что и как работает в питоне, или рассказывать сразу следствия не давая базу, но их много, и их логика странная, если про указатели не знать…

С точки зрения питона или лиспа указатель — странная конструкция. Если очень надо передать право на запись в какую-то внешнюю переменную, то логичнее передать замыкание. Если нужно значение, которое хранится в разных коллекциях и может изменяться из каждой, то это структура с одним полем. А указатель приходится описывать как число, являющееся индексом в некоем глобальном массиве, что позволяет менять массив, передавая в функцию значение индекса. И добавляя, что в более примитивных языках индекс указывает на самом деле не на объект, а на байт памяти, что позволяет получать непереносимое представление объектов в виде байтов и может служить быстрой но ненадёжной заменой сериализации.

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

Да, блин. Я то все понимаю. Проблема в том, что в языке без ссылок очень странно требовать их знание, чтобы понимать как передаются переменные. И если про них не знать, то это выглядит нелогично. Соотв. обучение начинает превращаться или в заучивание особых случаев или рассказ про указатели сильно раньше, чем стоит.

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

Так я не спорю. Языки без ссылок и указателей нужны, но НАДО чтобы логика исполнения их кода была понятна БЕЗ знания ссылок и указателей.

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

В питоне нет ничего кроме ссылок. Любая переменная в питоне это ссылка. Любой контейнер содержит ссылки (за исключением каких то новомодных арреев что ли). Весь питоний процесс это граф из объектов и ссылок н а них, этот граф можно вывести в .dot например, выглядит феерично.

На начальном уровне об этом можно не думать. Потом об этом думать приходиться. Это не баг и не фича, это особенность ЯП.

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

А хрен ли не думать?

Вот простой пример: у меня есть переменная age = 3, я хочу написать функцию, которая эту переменную увеличит до 12. Как мне это сделать? Подчеркиваю, я хочу именно чтобы ее изменила функцию, а не присвоить новой значение как результат какой-то функции.

Для питона ответ – никак. Хочешь менять, делай, например, список: age = [3], его внутри функции можно изменить.

В итоге получаем что для примитивов, у нас нет нормальных переменных в питоне.

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

Ну и как тут понимать «var += 1».

Для неизменяемых типов (всех) как var = var + 1 то есть возвращается новый неизменяемый объект. Для изменяемых как изменение объекта, на который ссылается var.

мы не можем увеличить значение переменной

Нет же. Мы можем увеличить значение переменной, но не можем увеличить значение объекта, который в ней сейчас (потому что значение 1 всегда 1).

Python: никак.

Верно. От того, что значение переменной передано в функцию, переменная измениться не может. Если надо менять именно значение, передавай список из одного элемента.

То есть в Питоне есть гарантия, что

a = b
foo(a)

всегда эквивалентно

foo(b)

Для Си++ нет.

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

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

void calc(int &a, int &b)
{
   a *= 2;
   return a + b;
}

int a = 2;
calc(2, 2) // 6
calc(a, a) // 8
monk ★★★★★
()
Ответ на: комментарий от monk

Ну вот то, что запись «var += 1» возвращает новый неизменяемый объект, а var[0] += 1 изменяет объект-список, несколько сложна для понимания.

Вообще неизменяемые объекты для примитивов это сложно для начала обучения программированию. Мы привыкли, что мы можем менять значения. В этом плане С++ сильно проще.

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

я хочу написать функцию, которая эту переменную увеличит до 12.

Вы хотите странного, это антипаттерн вообще то. Хороший ЯП затрудняет использование антипаттернов.

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

Никто не спорит что разделение на изменяемые и неизменяемые объекты в питоне это плохо. Но на начальном этапе обучения это не является проблемой (мы же про питон как обучающий ЯП говорим).

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

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

Ну а так то да, there is more then one way to kill a cat.

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

Мы привыкли, что мы можем менять значения. В этом плане С++ сильно проще.

Да ну? my_age(1) должно изменить значение 1?

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

Мы привыкли, что мы можем менять значения.

#include <stdio.h>

int main()
{
        char* h = "Hello";
        h[0] = '0';
        printf(h);
}
$ gcc -Wall test.c
$ ./a.out
Ошибка сегментирования
monk ★★★★★
()
Ответ на: комментарий от AntonI

Когда это передача по ссылке стала антипаттерном?

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

void reproduction(double  &biomass) {
    biomass = biomass * biomass;
}

void sanitize(double &biomass)  {
    biomass = 0.05 * biomass;
}

void simulation() {
    double biomass = 1.0;  // 1 gramm
    for(int time = 0; time < 100; time++) {
       reproduction(biomass);
 
       if(time == 10) sanitize(biomass);

       std::cout << "time: " << time << "; ";
       std::cout << "biomass: " << biomass << std::endl;
    }
}

Тут код получается логичным, мы работаем с биомассой и соотв. вызываем функции, которые меняют ее в соотв. с событиями.

Как это сделать на питоне? С примитивами – никак.

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

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

Да ну? my_age(1) должно изменить значение 1?

Так 1 это не переменная. Мы привыкли, что может менять значения переменных.

Чего ты мне тут по ногам стреляешь? :)

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

вызываем функции, которые меняют ее в соотв. с событиями.

Нормальные люди пишут biomass = reproduction(biomass) и biomass = sanitize(biomass) вместо изменяющих процедур. И все изменения переменной наглядны. А здесь как только типы не базовые, так любой оператор может переменную поменять. Или исключение выкинуть.

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

Так 1 это не переменная

Было написано «Мы привыкли, что мы можем менять значения».

Мы привыкли, что может менять значения переменных.

Это программисты на Си++ привыкли. Даже на Си функция значение переменной не меняла. Си++ предлагаешь как язык для обучения? Так там c = a + b может поменять значения a и b. Это разве хорошо?

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

Нормальные люди пишут

Зависит от того, с чем работаешь. Иногда удобнее считать, что ты работаешь с объектом и события (закодены как функции) его меняют.

Иногда удобнее считать, что ты рассчитываешь новое значение параметра и присваиваешь его.

В данном примере, логичней думать, что мы меняем состояние объекта, т.е. передавать по ссылке.

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

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

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

события (закодены как функции)

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

что мы меняем состояние объекта, т.е. передавать по ссылке

Если у тебя в переменной объект с изменяемым состоянием, то так его и описывай: в виде структуры.

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

который переопределять так, чтобы переменная будет меняться никто не будет

Синтаксически запрета нет. Даже компилятор не ругнётся. А значит случайно так сделать легче лёгкого. И будет крайне трудноуловимая ошибка.

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

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

Слушай, я тебе привел конкретный пример, который хорош для первых уроков программирования в школе.

А ты мне предлагаешь его усложнять до структур и пр.

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

Слушай, я тебе привел конкретный пример, который хорош для первых уроков программирования в школе.

Это плохой пример, так как учит плохому стилю программирования.

Как только начинает идти речь про изменение состояния надо вводить объекты и biomass.reproduction() гораздо логичнее, чем reproduction(biomass).

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

Функцию аргументом передать можно

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

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

Это хороший пример, и он учит хорошему стилю программирования.

Создавать структуру из одного поля странно, простые вещи, должны делаться просто. Какие структуры на первых занятиях по программированию? Ты о чем вообще? Ребята привыкли к «переменным», которые они видят на уроках физики, математики, биологии, они еще даже векторов в школе не проходили. Вот эта переменная тут и есть, и она меняется.

Структуры, объекты, неизменность, функционалы и пр. они потом, когда будет в них потребность. В этой задачи в них потребности нет.

reproduction(biomass) на первых порах гораздо логичней, чем biomass.reproduction(). Объединение данных и методов это не такая простая концепция, как кажется, и она нужна организации кода, а когда весь код это пара процедур – она явно избыточна.

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

Это хороший пример, и он учит хорошему стилю программирования.

Нет. Это плохой пример. Не надо так делать. И уж если разговор про моделирование, то либо делается полноценный класс модели в которой есть и biomass и время и остальные параметры, либо делают так говорил выше @monk.

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

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

Можно пример неудобства функциональной композиции в Питоне? По сравнению с любым другим языком. Вот в Си функциональная декомпозиция очень неудобна: compose не сделать, fold не сделать. В Си++ получше, его хотя бы можно сделать, но там, где в питоне достаточно написать

def compose(f, g):
  def r(x):
    return f(g(x))
  return r

В Си++ несколько десятков строк нетривиального кода.

«Широко применима» - это как измерять? ООП декомпозиция чаще применяется, чем функциональная. Но так всюду, где они есть обе, кроме разве Racket.

monk ★★★★★
()
Закрыто добавление комментариев для недавно зарегистрированных пользователей (со score < 50)