Здравствуйте, samius, Вы писали:
S>Про декартово произведение я знаю, не знал лишь что Nemerle может подать кортеж в метод, где параметры объявлены через запятую. F# вот так не может.
Здравствуйте, Kluge, Вы писали:
K>Здравствуйте, samius, Вы писали:
S>>Про декартово произведение я знаю, не знал лишь что Nemerle может подать кортеж в метод, где параметры объявлены через запятую. F# вот так не может.
K>Это работает. А как F# неможет?
Извиняюсь, ляпнул не проверив.
Для меня это неожиданность. Спасибо!
Здравствуйте, FR, Вы писали:
FR>Здравствуйте, samius, Вы писали:
S>>Да, в F#-е эти туплы хоть и имеют должную поддержку языка, но вызов метода с передачей кортежа вместо аргументов через запятую (как в немерле) и там не реален. Потому то меня и смутила форма записи типа кортежа со звездой приминительно к немерле (я ожидал от его кортежей чего-то подобного F#-у).
FR>В F# вызов функций с несколькими аргументами это просто сахар для карринга, поэтому никакой "совместимости" и не может быть. Но никто не запрещает (хотя это плохой стиль) использовать вместо функций с несколькими аргументами функцию с одним аргументом кортежом, тогда все будет отлично совместимо.
ИМХО лучше использовать сахар раз-уж он есть и если нужно передать (int * int) в int -> int -> 'a то использовать <|| & ||> вместо того, что-бы менять тип параметра на кортеж.
Здравствуйте, Kluge, Вы писали:
K>Здравствуйте, samius, Вы писали:
S>>Про декартово произведение я знаю, не знал лишь что Nemerle может подать кортеж в метод, где параметры объявлены через запятую. F# вот так не может.
K>
K>let f (a, b) = a+b;;
K>let p = 3,5;;
K>f p;;
K>
K>Это работает. А как F# неможет?
Точнее я полагал что так не получится:
open System.Collections.Generic
let p = (3,5)
let d = new Dictionary<_,_>()
d.Add(p)
Здравствуйте, Kluge, Вы писали:
K>ИМХО лучше использовать сахар раз-уж он есть и если нужно передать (int * int) в int -> int -> 'a то использовать <|| & ||> вместо того, что-бы менять тип параметра на кортеж.
Здравствуйте, AndrewVK, Вы писали:
AVK>Совместимы. Но только в пределах одной сборки.
Может модуля?
Сдается мне, они совместимы в пределах одной сессии компилятора, который способен сгенерить один анонимный тип на все "совместимые" случаи.
Здравствуйте, samius, Вы писали:
S>А как насчет |||> или ||||> ?
В библиотеке есть до 3х, но если очень нужно можно сделать хоть до 18ти и дальше
Но в моей практике если есть кортеж, то это значения связанные смыслом, а значит и функция принимает в качестве параметра кортеж.
Если мы использовали кортеж для возвращения нескольких, несвязанных, значений то лучше сразу сделать декомпозицию и передавать дальше как два значения.
Здравствуйте, thesz, Вы писали:
T>Здравствуйте, VladD2, Вы писали:
VD>>Здравствуйте, thesz, Вы писали:
T>>>Видишь ли, эти самые безымянные записи с именованными полями нужны ровно для того, чтобы не перепутать startTime и endTime. Поддержать инвариант startTime <= endTime. Сделать их "типы" "зависящими" от их значений. Зависимыми, иными словами. VD>>Инвариантом здесь и не пахнет. Не надо домысливать. VD>>Все это нужно чтобы помочь человеку. В первую очередь — это возможность доступа к полям по имени. Скажем, если у нас есть некий запрос возвращающий список кортежей, то куда удобнее обращаться к полям кортежей по именам, а не через позиции.
T>Или по сравнению с образцом.
T>>>Если смотреть на это с такой точки зрения, то всё это обсуждение яйца выеденного не стоит. VD>>Не очень понятно с чего бы это, но на то они и разные точки зрения.
T>Всё, что ты делаешь (и я делаю, и кто-либо ещё делает в районе проектирования любых ЯП), направлено на уменьшение количества ошибок, допускаемых программистами.
T>Это единственная разумная точка зрения. "Мы все уменьшаем количество ошибок наших пользователей".
T>Далее идёт оценка размена — какие ошибки мы уменьшаем, какие увеличиваем. Где мы потратим больше времени, где меньше — второй вариант оценки.
T>Так вот, с этой точки зрения обсуждение обращения по именами полей безымянных структур выглядит разменом даже не самих пешек, а разменом пыли с тех частей доски, на которых эти пешки стояли.
Сергей, разъясните, пожалуйста.
В хаскеле советуют вместо туплов создавать отдельные типы. Ну и вот, создам я, например,
будет паттерн-матчинг, который учитывает все, даже не используемые части.
print_first_name (FIO _, fname, _) = print fname
По-вашему, это пыль где пешки стояли?
T>А вот наличие имён для индикации инвариантов уже более интересно. Про наличие инвариантов и говорить отдельно не стоит, и так понятно, что это круто.
T>>>В Хаскель не попадают идеи из C#, в отличии от противоположного направления. VD>>Возможно тебя это рассторит, но подовляющему большинству программистов плевать на хаскель и на то что в него попадает. VD>>И плевать, на то что ты не можешь пройти мимо любой темы, посвященной дизайну ЯП, где забыли упомянуть Наскель.
T>Я так думаю, что это их проблемы, не мои.
T>Это они не знакомы с Хаскелем и потому, начиная говорить о функциональных языках программирования, сворачивают на то, что им известно.
T>>>Поэтому выгодней учить Хаскель. Что я и делаю. VD>>Ну, учи. Что к другим то приставать?
T>Я альтруист.
VD>>Мне Hasskel без надобнсоти. Что на нем можно сделать? Чистые вычисления меня не интересуют.
T>А зря.
VD>>От иероглифической записи меня не прем (иначе я наверно перся бы от K или J). Мне нужен инструмент позволяющий решать проблемы реального мира.
T>Это любой ЯП общего назначения.
T>Интересно, ты не упомянул "наиболее эффективным образом".
T>>>Но ты спрашивай, я объясню. VD>>Мне тебя не о чем спрашивать. Твоя позиция почти всегда деструктривно. Потому с тобой просто не интересно разговаривать. Вместо высказывания интересный мыслей ты постоянно выёживашся и потнушся. VD>>Научись воспринимать окружающих как равных. Объяснять свою точку без понтов, воспринимать чужую точку зрения. Тогда с тобой будет интересно вести беседы. А так одно раздражения от общения с тобой получаешь.
T>Ух ты!
T>Это же комплимент.
T>Поскольку я слышу это от человека, которому последние два параграфа говорят гораздо чаще, чем мне.
Да, попутал, запятые лишние.
S>Да, паттерн матчинг будет иметь место. Record syntax дешугарится в набор функций аля
S>first (FIO _ first _) = first
S>Но разве он учитывает все? Только то что используется.
Нет, я использую только first, а должен писать "_" на каждую часть типа FIO, которую я *не использую*. <-- Внимание, плохо пахнет.
T>>По-вашему, это пыль где пешки стояли?
S>Речь ведь идет об fio.first vs first fio? Если да, то введем forward application
S>(|>) :: a -> (a -> b) -> b
S>x |> f = f x
S>-- тогда
S>print_first_name fio = fio |> first |> print
S>fio|>first ведь не сильно хуже чем fio.first? S>Потому — да, пыль.
Порядок записи — пыль. first в глобальном namespace вместо namespace FIO — не пыль, а проблема.
Здравствуйте, Temoto, Вы писали:
T>Это рекорды, которые, как известно, в хаскеле глобальные на модуль, соответственно указанный выше код на самом деле создаёт функцию
T>
first :: FIO -> String
T>что, конечно, здорово, но нельзя сделать FIO{last::String, first...etc} И MyList a{last::a, first::a,...etc} в одном модуле.
Разве это критично?
T>Да, попутал, запятые лишние.
S>>Да, паттерн матчинг будет иметь место. Record syntax дешугарится в набор функций аля T>
S>>first (FIO _ first _) = first
T>
S>>Но разве он учитывает все? Только то что используется.
T>Нет, я использую только first, а должен писать "_" на каждую часть типа FIO, которую я *не использую*. <-- Внимание, плохо пахнет.
В случае record syntax пишет компилятор, полностью освобождая от необходимости подсчета позиций полей.
S>>fio|>first ведь не сильно хуже чем fio.first? S>>Потому — да, пыль.
T>Порядок записи — пыль. first в глобальном namespace вместо namespace FIO — не пыль, а проблема.
И ее решают с помощью модулей. Нет?
Глобальный namespace — вообще отдельная проблема. И в других языках ее решают по-разному. Например в C# — любые объявления кроме namespace-ов и delegate-ов могут быть только внутри классов. В будущих версиях F# глобальные определения тоже частично запретят (Warning: Files in libraries or multiple-file applications should begin with a namespace or module declaration, e.g. 'namespace SomeNamespace.SubNamespace' or 'module SomeNamespace.SomeModule'. This will be required in a future version of F#)
Здравствуйте, Temoto, Вы писали:
T>>>Порядок записи — пыль. first в глобальном namespace вместо namespace FIO — не пыль, а проблема.
S>>И ее решают с помощью модулей. Нет?
T>Это лечение симптомов, а не проблемы. "Костыль".
Предлагаю определиться. Если выделенное — проблема, то лечится она модулями + import qualified. Если выделенное — симптом, то что же на самом деле является проблемой?
Может быть проблемой является отсутствие перегрузки функций в стиле С++, чтобы можно было определять рядом
first (FIO _ first _) = first
first (MyList _ first _) = first
T>>>>Порядок записи — пыль. first в глобальном namespace вместо namespace FIO — не пыль, а проблема.
S>>>И ее решают с помощью модулей. Нет?
T>>Это лечение симптомов, а не проблемы. "Костыль".
S>Предлагаю определиться. Если выделенное — проблема, то лечится она модулями + import qualified. Если выделенное — симптом, то что же на самом деле является проблемой? S>Может быть проблемой является отсутствие перегрузки функций в стиле С++, чтобы можно было определять рядом S>
S>first (FIO _ first _) = first
S>first (MyList _ first _) = first
S>
S>?
Да, выделенное — проблема. Модули+import это костыль. Лечение проблемы состояло бы в возможности определить несколько типов с одинаковыми названиями частей в одном модуле. Например, FIO.first.
Хотя, сейчас с утра мне это уже не кажется так чтоб уж очень большой проблемой.
Здравствуйте, Temoto, Вы писали:
T>Нет, я использую только first, а должен писать "_" на каждую часть типа FIO, которую я *не использую*. <-- Внимание, плохо пахнет.
foo ComplexRecord{recField=var} = doSomethingWith var