LINUX.ORG.RU

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

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

В Racket cons не базовый тип. Макросы на синтаксических объектах.

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

Это проблема многих высокоуровневых языков, например в Java я столкнулся с невозможностью адекватно написать коллекцию, потому что там невозможно написать общий код для Integer и int, и генерики принимают только объекты, а они занимают слишком много памяти по сравнению с примитивами. (А еще там индекс менее 32 бита, что не позволяет создавать массивы byte более 4гб, ну это отдельная тема)

В этом плане С намного более единообразен (а ассемблер на фон-неймановской архитектуре достигает вершины, там не только данные представлены в виде char[], но и код).

И этому есть много реальных применений, вот два интересных:

  • В некоторых мультиплеерных играх, сервер хранит предыдущее отправленное игрокам состояние, и текущее вычисленное, когда его нужно отправить, он запускает функцию:
    void write_diff(int socket, const void *old_state, const void *new_state);
    
    Которая отправляет клиенту данные вида [(offset, byte[]), ...], и клиент этими данными просто патчит свою память кодом вида:
    for (auto chunk : server.read()) 
      memcpy(&my_state[chunk.offset], chunk.data, chunk.data.size()); 
    
  • Консервативный сборщик мусора, такой как Boehm GC, сканирует память приложения, и ищет указатели, если указатель на память найден, то она считается используемой. Используется за пределами С, например в Guile.

Common Lisp родня Forth’у: пишем программу в REPL, тестируем тут же, проектируем после того, как что-то выросло. Racket родня скорее Java: начинать писать приходится с декомпозиции на модули и описание типов/контрактов.

При низкоуровневой работе, первым делом рекомендуется написать эмулятор устройства, что бы можно было тестировать свой код (мокинг). Работа в образе никогда не отмечается и является побочным эффектом организации Forth-системы. Заплаточное программирование считается вредным. Чарльз Мур против документации в коде, и вообще комментариев.

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

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

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

В Racket cons не базовый тип. Макросы на синтаксических объектах.

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

Это проблема многих высокоуровневых языков, например в Java я столкнулся с невозможностью адекватно написать коллекцию, потому что там невозможно написать общий код для Integer и int, и генерики принимают только объекты, а они занимают слишком много памяти по сравнению с примитивами.

В этом плане С намного более единообразен (а ассемблер на фон-неймановской архитектуре достигает вершины, там не только данные представлены в виде char[], но и код).

И этому есть много реальных применений, вот два интересных:

  • В некоторых мультиплеерных играх, сервер хранит предыдущее отправленное игрокам состояние, и текущее вычисленное, когда его нужно отправить, он запускает функцию:
    void write_diff(int socket, const void *old_state, const void *new_state);
    
    Которая отправляет клиенту данные вида [(offset, byte[]), ...], и клиент этими данными просто патчит свою память кодом вида:
    for (auto chunk : server.read()) 
      memcpy(&my_state[chunk.offset], chunk.data, chunk.data.size()); 
    
  • Консервативный сборщик мусора, такой как Boehm GC, сканирует память приложения, и ищет указатели, если указатель на память найден, то она считается используемой. Используется за пределами С, например в Guile.

Common Lisp родня Forth’у: пишем программу в REPL, тестируем тут же, проектируем после того, как что-то выросло. Racket родня скорее Java: начинать писать приходится с декомпозиции на модули и описание типов/контрактов.

При низкоуровневой работе, первым делом рекомендуется написать эмулятор устройства, что бы можно было тестировать свой код (мокинг). Работа в образе никогда не отмечается и является побочным эффектом организации Forth-системы. Заплаточное программирование считается вредным. Чарльз Мур против документации в коде, и вообще комментариев.

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

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

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

В Racket cons не базовый тип. Макросы на синтаксических объектах.

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

Это проблема многих высокоуровневых языков, например в Java я столкнулся с невозможностью адекватно написать коллекцию, потому что там невозможно написать общий код для Integer и int, и генерики принимают только объекты, а они занимают слишком много памяти по сравнению с примитивами.

В этом плане С намного более единообразен (а ассемблер на фон-неймановской архитектуре достигает вершины, там не только данные представлены в виде char[], но и код).

И этому есть много реальных применений, вот два интересных:

  • В некоторых мультиплеерных играх, сервер хранит предыдущее отправленное игрокам состояние, и текущее вычисленное, когда его нужно отправить, он запускает функцию:
    void write_diff(int socket, const void *old_state, const void *new_state);
    
    Которая отправляет клиенту данные вида [(offset, byte[]), ...], и клиент этими данными просто патчит свою память кодом вида:
    for (auto chunk : server.read()) 
      memcpy(&my_state[chunk.offset], chunk.data, chunk.data.size()); 
    
  • Консервативный сборщик мусора, такой как Boehm GC, сканирует память приложения, и ищет указатели, если указатель на память найден, то она считается используемой. Используется за пределами С, например в Guile.

Common Lisp родня Forth’у: пишем программу в REPL, тестируем тут же, проектируем после того, как что-то выросло. Racket родня скорее Java: начинать писать приходится с декомпозиции на модули и описание типов/контрактов.

При низкоуровневой работе, первым делом рекомендуется написать эмулятор устройства, что бы можно было тестировать свой код (мокинг). Работа в образе никогда не отмечается и является побочным эффектом организации Forth-системы. Заплаточное программирование считается вредным. Чарльз Мур против документации в коде, и вообще комментариев.

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

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

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

В Racket cons не базовый тип. Макросы на синтаксических объектах.

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

Это проблема многих высокоуровневых языков, например в Java я столкнулся с невозможностью адекватно написать коллекцию, потому что там невозможно написать общий код для Integer и int, и генерики принимают только объекты, а они занимают слишком много памяти по сравнению с примитивами.

В этом плане С намного более единообразен (а ассемблер на фон-неймановской архитектуре достигает вершины, там не только данные представлены в виде char[], но и код).

И этому есть много реальных применений, вот два интересных:

  • В некоторых мультиплеерных играх, сервер хранит предыдущее отправленное игрокам состояние, и текущее вычисленное, когда его нужно отправить, он запускает функцию:
    void write_diff(int socket, const void *old_state, const void *new_state);
    
    Которая отправляет клиенту данные вида [(offset, byte[]), ...], и клиент этими данными просто патчит свою память кодом вида:
    for (auto chunk : server.read()) 
      memcpy(&my_state[chunk.offset], chunk.data, chunk.data.size()); 
    
  • Консервативный сборщик мусора, такой как Boehm GC, сканирует память приложения, и ищет указатели, если указатель на память найден, то она считается используемой. Используется за пределами С, например в Guile.

Common Lisp родня Forth’у: пишем программу в REPL, тестируем тут же, проектируем после того, как что-то выросло. Racket родня скорее Java: начинать писать приходится с декомпозиции на модули и описание типов/контрактов.

При низкоуровневой работе, первым делом рекомендуется написать эмулятор устройства, что бы можно было тестировать свой код (мокинг). Работа в образе никогда не отмечается и является побочным эффектом организации Forth-системы. Заплаточное программирование считается вредным. Чарльз Мур против документации в коде, и вообще комментариев.

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