контроль за соблюдением правил возложен на компилятор, и попробуй не соблюсти хоть одно из них.
С синтаксическими правилами вопросов нет, проконтролирует. Но можно ведь написать совершенно верную синтаксически, но, тем не менее, абсолютно вопиющую дичь?
Ну линтер ещё, может, пару широко известных образцов явной дичи отловит, и всё. Твори, художник, как велит тебе сердце %)
если правильно делать классы, компоненты и прочее, с нужными интерфейсами и ограничениями
И компилятор проверяет, что классы сделаны правильно, не только с чисто синтаксической точки зрения? Ой-вей.
Но можно ведь написать совершенно верную синтаксически, но, тем не менее, абсолютно вопиющую дичь?
при правильной разработке нельзя. все значения имеют тип, ассоциированные методы, нужные правила преобразования из типа в тип.
Лопаты нельзя складывать с землекопами, а вместо абсолютного пути подставить относительный путь или просто строку. поскольку при правильной разработке это значения разных типов. это уже не синтаксические правила, а семантические, на основе системы типов.
Синтаксически всё правильно, все типы сходятся, комар носа не подточит. Компилятор доволен. Но ведь дичь же?
это не имеет отношения к типам. это имеет отношение к психической нормальности пишущего. в любом языке можно написать программу которую нельзя прочитать, например если все идентификаторы сделать случайными строками длины 256 байт. компьютеру все равно, а человек с ума сойдет.
у вас неверная аргументация. вы говорите примерно следующее, показывая пальцем на велосипедиста под колесами автомобиля - ну вот, никакие ваши ПДД, светофоры, и разметки, не спасли несчастного от гибели под колесами. значит никакие ваши пдд и не нужны. логично? логично!
нелогично. без пдд и светофоров, все б давно друг друга передавили и движения не было б вообще.
До макросов я еще не дошел, поэтому не понимаю что такое «негигиеничный». Но похоже что второй namespace был введен для решения проблемы порожденной гибкостью языка. Хотя все равно странно иметь две переменные с одинаковым именем и при этом в одной из них данные, а в другая - функция.
Нет никаких двух namespaces. Это выдумано для студентов.
В Lisp и Scheme любое имя указывает на структуру symbol в памяти. В Lisp эта структура содержит отдельные поля(указатели) для переменной и функции.
Все symbols часть программы на Lisp как объекты в памяти, не исчезают после компилятора как в других языках.
Почитал историю Лиспа и Scheme и вот что интересное заметил. Одну из фундаметнальных книг по лиспу написал Guy L Steele. Он же потом задизайнил Scheme убрав из лиспа все шереховатости и странности. После чего задизайнил Java которая стала очень популярной.
«Шероховатости и странности» это только если в учебном курсе.
В Lisp ничего странного нет.
Он пришёл в команду Java когда язык уже был разработан.
В Lisp и Scheme любое имя указывает на структуру symbol в памяти. В Lisp эта структура содержит отдельные поля(указатели) для переменной и функции.
В Scheme не на структуру, а на значение. Там структура излишня. В (Common) Lisp, в зависимости от реализации, может быть или ссылка на структуру или две ссылки, выбираемые в зависимости от контекста (головной элемент списка читается из пространства имён функций, остальные из пространства имён переменных). Второй путь чаще, так как нет функции, которая возвращала бы эту самую структуру с двумя полями.
Все symbols часть программы на Lisp как объекты в памяти, не исчезают после компилятора как в других языках.
Также зависит от реализации. При загрузке скомпилированного представления в памяти гарантированно присутствуют только символы пакета из кода программы. Символы, использованные при компиляции, в скомпилированном представлении сохраняться не обязаны (например, имена локальных переменных и функций).
вы говорите примерно следующее, показывая пальцем на велосипедиста под колесами автомобиля - ну вот, никакие ваши ПДД, светофоры, и разметки, не спасли несчастного от гибели под колесами. значит никакие ваши пдд и не нужны.
Я говорю — никакие светофоры и правила сами по себе, одним своим наличием, никого не спасут; чтобы правила работали, нужно, чтобы участники движения их знали и соблюдали — были квалифицированными участниками движения.
Автоматические штрафы за превышение скорости по камерам никак не мешают лауреатам премии Дарвина наматываться на столбы и залетать под фуры и никак не помогают тем, кто и так мотивирован заботиться о безопасности движения.
в монголии, в соц. времена, они там из монголов-кочевников делали оседлых и всякий пролетариат. строили города, дома, школы, больницы, заводы и все такое.
ну так вот. давали такому кочевнику квартиру, а он и его предки жили в юрте лет 1000, а то и более. и чтобы не изменять стилю, кочевник просто ставил посреди большой комнаты маленькую юрту, и жил там, продолжая традицию.
короче. вам дали ООП и строгую типизацию, привыкайте, меняйтесь, и нечего жить в юрте динамических языков, когда вам дали удобства.
Так это и есть юрта. В степи годится, в квартире не очень. Просто вы настолько привыкли к ООП и типопоклонничеству, что хотите протащить их буквально везде, куда надо и куда не надо, не считаясь с последствиями.
юрта - это примитивное сооружение, не требующее особых навыков при строительстве.
интерпретаторы нетипизированных языков - это примитивные системы, просто исполняющие AST, где узлы имеют метод eval(то есть «вычислить»). плюс словарь символов.
нашел декларацию символа - занес в «словарь», нашел определение - прицепил к символу. видишь что надо вычислить символ - нашел его в словаре(не нашел - ругнулся) и запустил его метод eval, - или получаешь результат или ругань, что параметры например неверные. и все.
плюс сборка мусора, поскольку все это мусорит безмерно.
это и есть юрта.
а в ооп и строгой типизации все существенно сложней.
а в ооп и строгой типизации все существенно сложней.
Ну так и ставить юрту в квартире для обычного человека гораздо сложнее, чем просто жить в этой квартире без юрты, а главное, совершенно непонятно, зачем это делать, если у тебя крыша не протекает. Всё сходится %)
интерпретаторы нетипизированных языков - это примитивные системы
Во-первых, типы там обычно есть — но только у значений, а не их имён. Идея, что у имени может быть тип, на самом деле довольно неуклюжая и костылеобразная. Зачем имени тип? Мы не используем (обычно) в вычислениях имена, мы используем объекты, на которые они указывают.
Во-вторых, «примитивные», то есть простые — это достоинство. Их гораздо легче понимать и использовать.
интерпретаторы нетипизированных языков - это примитивные системы, просто исполняющие AST, где узлы имеют метод eval(то есть «вычислить»). плюс словарь символов.
И какие это языки? Названия.
а в ооп и строгой типизации все существенно сложней.
C++ templates are invariant. They don’t support covariance or contravariance.
В Scheme только:
(symbol? obj)
(symbol->string symbol)
(string->symbol string)
В Chez Scheme есть не только это. На котором реализован Racket.
(string->uninterned-symbol string)
(symbol->string symbol)
(property-list symbol)
(putprop symbol key value)
(getprop symbol key)
(remprop symbol key)
Sheme-еры пытались затянуть в Emacs идею писать расширения на JS, Lua, другие языки. Просто в виде синтаксиса, не имеются в виду те реализации которые есть для тех языков.
Это не Scheme, а расширения. В некоторых реализациях даже рестарты есть.
И наличие (property-list symbol) не гарантирует, что символ является структурой. Я легко могу сделать property-list/putprop/getprop/remprop принимающие целое число. Тогда будете утверждать, что в числе внутри хранится структура?
Это не Scheme, а расширения. В некоторых реализациях даже рестарты есть.
Scheme был нужен для учебного курса.
Scheme нравится своими экспериментами, как сборщик мусора в Chicken Scheme.
И наличие (property-list symbol) не гарантирует, что символ является структурой. Я легко могу сделать property-list/putprop/getprop/remprop принимающие целое число. Тогда будете утверждать, что в числе внутри хранится структура?
Буду использовать нормальный Lisp где название symbol-а всегда отличается от числа.
В Racket(не Scheme) был эксперимент по добавлению статических типов.
В Lisp это стандартная возможность с 1980-x.
Если выше это валидная запись в Racket, то это странно. List по принципу полиморфный без ограничений.
С чего это? Не более полиморфный, чем вектор. В тот тоже по умолчанию можно произвольные данные складывать.
Common Lisp, тип фукции которая принимает vector целых чисел размером 3 элемента, и второй аргумент целое число. Возвращает cons.
Вот именно. Единственная типизированная коллекция — это вектор. Даже hash и тот принципиально нетипизированный.
А в Racket я могу указывать писать типы «пара из числа и строки», «хэш чисел на строки» и даже «функция, возвращающая неизменяемый массив с типом элементов, совпадающим с типом обоих аргументов»
Вот эта типизация в Racket она наверное замедляет программу вместо ускорения как в Common Lisp.
«Benchmarks Game», для Racket даже не пытаются использовать типы.
Ну она хотя бы написана на Racket. В других лиспах я такого не припомню, да и надо же как-то одним лисперам унижать других лисперов не из своего загончика. Наличие собственного блокнота с брейкпоинтами IDE хоть какое-то преимущество.
Палка о двух концах: так со одной стороны для CL и схем обычно используют Emacs, с другой стороны разработчики могут заточить свою ide для максимально удобной работы конкретно для своего языка. Но я зеленый в лиспах и схемах так что колоссальной разницы между DrRacket и Emacs не заметил, разве что в DrRacket можно ставить брейкпоинты по строкам (но может так и в емаксе для лиспа можно)