LINUX.ORG.RU

Избранные сообщения Kuzy

Представление иррациональных чисел без потери точности

Форум — Development

Привет. Задумал совместить важное и нужное с полезным, а именно решил начать изучать haskell, а заодно и написать на нём очередную имэджбоарду набор сценариев/или какой-то проектик (пока не сформировал мысль, что именно это должно быть, возможно, некоторое моделирование каких-нибудь процессов)

Нужны комплексные числа. Действительная и мнимая часть их может быть иррациональной. Числа pi там скорее всего не будет, но будет (sqrt 2), насчёт остальных корней пока не знаю, актуально ли. Ну в идеале чтобы можно было представить числа в любой рациональной степени (2 в степени 1/2, например, что и есть sqrt 2).

Хотелось, чтобы эти степени и корни не вычислялись, а представлялись в памяти как есть (haskell ведь ленивый язык?), и в случае необходимости сами себя упрощали (если я умножаю sqrt 2 на самого себя, я получаю же 2?)

Может быть и не любое иррациональное число можно так представить... но мне и не все нужны, а только простые случаи.

Понятно, почему я не хочу real/float - неизбежные потери точности. Можно постоянно применять округления, но, думаю, тут я могу получить неожиданности. Потери в производительности меня не смущают, не думаю, что они пока актуальны.

Так вот, мой вопрос в том - есть ли что-то уже готовое может быть? Я ничего не нашёл... похоже, придётся делать самому. Стандартный тип Complex вроде как работает с Float/Double либо Int, либо Rational, что немного не то... если я не ошибся?

P.S. Знаю, что, возможно, всё это есть в Maple, и, может быть, даже в mathematica или maxima, но это как-то «не спортивно» что ли. :) Да и не хочется зависеть от математических пакетов.

 ,

BattleCoder
()

Хвостовая рекурсия.

Форум — Development

Разбираюсь с хвостовой рекурсией.

Реализовал алгоритм поиска пирамидального числа:

-- recursion version
--
fermaPyr 0 = 0
fermaPyr n = fermaTria n + fermaTria (n - 1)

fermaTria 0 = 0
fermaTria n = n + fermaTria (n - 1)

-- tail recursion version
-- 
fermaPyrAcc n = let fAcc 0 a = a
                    fAcc n a = fAcc (n - 1) (fermaTriaAcc n + a)
                in fAcc n 0

fermaTriaAcc n = let fAcc 0 a = a
                     fAcc n a = fAcc (n - 1) (n + a)
                 in fAcc n 0

-- tail recursion ver.2
--
fermaPyrAcc2 0 = 0
fermaPyrAcc2 n = fermaTriaAcc n + fermaTriaAcc (n - 1)



main = do
    let a = fermaPyr 1000000
        b = fermaPyrAcc 10000
        c = fermaPyrAcc2 1000000
    putStrLn $ show a
    --putStrLn $ show b
    --putStrLn $ show c

Запуск варианта а:

     177,963,104 bytes allocated in the heap
     187,666,896 bytes copied during GC
      36,388,928 bytes maximum residency (8 sample(s))
          36,384 bytes maximum slop
              82 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0       237 colls,     0 par    0.13s    0.13s     0.0005s    0.0014s
  Gen  1         8 colls,     0 par    0.09s    0.10s     0.0119s    0.0285s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    0.10s  (  0.10s elapsed)
  GC      time    0.22s  (  0.22s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.01s  (  0.01s elapsed)
  Total   time    0.33s  (  0.33s elapsed)

  %GC     time      67.7%  (67.7% elapsed)

  Alloc rate    1,831,837,945 bytes per MUT second

  Productivity  32.3% of total user, 31.9% of total elapsed

Всё нормально, расход памяти, как и ожидалось, немалый, время исполнения тоже.

Запускаю вариант b:

   3,201,017,336 bytes allocated in the heap
         697,536 bytes copied during GC
          46,240 bytes maximum residency (2 sample(s))
          23,392 bytes maximum slop
               1 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0      6104 colls,     0 par    0.03s    0.03s     0.0000s    0.0000s
  Gen  1         2 colls,     0 par    0.00s    0.00s     0.0001s    0.0002s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    1.96s  (  1.98s elapsed)
  GC      time    0.03s  (  0.03s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time    1.99s  (  2.01s elapsed)

  %GC     time       1.7%  (1.7% elapsed)

  Alloc rate    1,635,694,726 bytes per MUT second

  Productivity  98.3% of total user, 97.4% of total elapsed

Здесь, памяти расходуется гораздо меньше, но время исполнения… при аргументе на 2 порядка меньше, чем в других вариантах, работает в несколько раз медленнее. Увеличив аргумент на порядок, я уже не дожидался окончания расчётов.

Вариант с:

     128,057,440 bytes allocated in the heap
          29,752 bytes copied during GC
          46,240 bytes maximum residency (2 sample(s))
          23,392 bytes maximum slop
               1 MB total memory in use (0 MB lost due to fragmentation)

                                    Tot time (elapsed)  Avg pause  Max pause
  Gen  0       243 colls,     0 par    0.00s    0.00s     0.0000s    0.0001s
  Gen  1         2 colls,     0 par    0.00s    0.00s     0.0001s    0.0002s

  INIT    time    0.00s  (  0.00s elapsed)
  MUT     time    0.08s  (  0.09s elapsed)
  GC      time    0.00s  (  0.00s elapsed)
  RP      time    0.00s  (  0.00s elapsed)
  PROF    time    0.00s  (  0.00s elapsed)
  EXIT    time    0.00s  (  0.00s elapsed)
  Total   time    0.08s  (  0.09s elapsed)

  %GC     time       2.0%  (2.1% elapsed)

  Alloc rate    1,571,481,972 bytes per MUT second

  Productivity  97.8% of total user, 94.8% of total elapsed

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

Для меня не очевидна разница между вариантами b и с. Почему оно так? Я ожидал, что вариант b будет самым лучшим т.к. в функции fermaPyrAcc2 нет хвостовой рекурсии, она только в её внутреннем цикле.

 

HolyBoy
()

[scheme][haskell][oop][fp] Мысли вслух

Форум — Development

Была на ЛОРе такая тема — [Haskell] простой вопрос. Хотелось бы немножко её развить и высказаться на тему предпочтения того или иного языка при изучении ФП (графомания mode on :)).

У Scheme есть довольно давняя история использования в качестве подопытного языка в курсах изучения ФП. Я не знаю чем это вызвано, но факт остаётся фактом — есть известный курс у MIT (или был?) и разные полезные книжки — SICP, HTDP, PLAI, OOPLAI, которые обычно и советуют читать если нужно ознакомиться с ФП.

Касательно SICP — одним из сторонников использования ML для целей изучения ФП была написана статья (http://www.cs.kent.ac.uk/people/staff/dat/miranda/wadler87.pdf) в которой достаточно хорошо освещены некоторые недостатки Scheme. Если говорить про Haskell, то тут всё так же. Далее, по пунктам (опуская кое-что из того что уже было в той статье).

Более явный синтаксис

Вместо

(define (foo x y z)
  (if (> (+ x (* y z) 1) 7) (print (+ x y)) (print (- x y))))

будет

foo x y z = if x + y * z + 1 > 7 then print $ x + y else print $ x - y

при этом по-прежнему можно написать выражение в префиксной форме:

(if' ((>) ((+) x ((*) y z) 1) 7) (print ((+) x y)) (print ((-) x y)))

почти как в Scheme. То есть, кроме префикса также есть (расширяемый пользователем) инфикс (в том числе функции вроде ($) и (.) позволяющие в некоторых случаях опускать лишние аргументы у функций и некоторые скобки в выражениях) и разные специальные формы (вроде if, let, лямбды и т.п.). Во всём что не касается макросов это более удобно. S-выражения обретают свой особый смысл только когда доходит до их цитирования:

'(if (> (+ x (* y z) 1) 7) (print (+ x y)) (print (- x y)))

и разбора с целью написания макросов. Тем не менее, для изучения именно ФП эта возможность незначительна (ФП не про макросы, в SICP и HTDP не ни слова про макросы, в PLAI есть только немного, в OOPLAI — побольше). Про то как правильно (ну, _правильно_, то есть без использования s-выражений) организовывать символьные вычисления (вроде дифференцирования из SICP) также расказывается в упомянутой статье.

Каррированные функции

Такое определение, например:

(define add
  (lambda (n)
    (lambda (m)
      (+ m n))))

заменяется простым

add = (+)

так как все функции уже каррированные (позволяют частичное применение). Фактически, в хаскеле функция с n аргументами сразу задаёт n разных функций (выбор конкретной функции осуществляется во время компиляции и не имеет эффекта во время выполнения). Некаррированные функции это функции от кортежей (те и другие переводятся друг в друга с помощью ФВП carry/uncarry).

Частичное применение, секции, pointfree запись

add2 = (+ 2)

add2 5
7

вместо

(define add2 (add 2))

(add2 5)
7

Мутабельные замыкания

Это единственная вещь которая есть в Scheme и которую можно не увидеть сразу в хаскеле (и про неё нет в той статье). Тот тред был как раз про них. Чтобы прояснить этот момент, ниже приводятся некоторые примеры из OOPLAI и их аналоги на хаскеле.

Простейший вариант:

(define counter
  (let ((count 0))
    (lambda ()
      (begin
        (set! count (add1 count))
        count))))

(counter)
1
(counter)
2

аналог:

counter = (=~ (+ 1)) <$> new 0

тут (=~ (+ 1)) играет роль мутирующего «метода», а (new 0) — мутируемого «объекта», (<$>) — применение «диспетчера» (тут — просто единичный анонимный «метод»). Вся конструкция функториальная (не монадическая). Использование:

ctr <- counter      -- Инстанцирование класса counter объектом ctr.
ctr                 -- Применение единственного метода ((=~ (+ 1)) который).
1                   -- Результат.
ctr                 -- Снова.
2                   -- Другой результат.

Чуть более сложный пример:

(define counter-
  (let ((count 0))
    (lambda (cmd)
      (case cmd
        ((dec) (begin
                 (set! count (sub1 count))
                 count))
        ((inc) (begin
                 (set! count (add1 count))
                 count))))))

(counter- 'inc)
1
(counter- 'dec)
0

Для начала определим имена методов dec и inc:

data CounterMethod = Dec | Inc

это не символы и не строки (так что код не будет ill-typed как в примере на Scheme, иначе говоря, применение несуществующего метода не пройдёт компиляции). И теперь функцию:

counter' = dispatch <$> new 0
  where dispatch obj Dec = obj =~ flip (-) 1
        dispatch obj Inc = obj =~ (+ 1)

тут dispatch играет роль диспетчеризирующей функции которая получает объект (obj) и имя метода, а затем изменяет объект (как того требует метод). (new 0) — начальный объект.

Пример:

ctr <- counter'     -- Инстанцирование класса counter' объектом ctr.
ctr Inc             -- Применение метода Inc на объекте ctr.
1
ctr Inc
2
ctr Inc
3
ctr Dec             -- Тут уже метод Dec.
2
ctr Dec
1
ctr Dec
0

Тут применение (ctr Inc) весьма похоже на каноничное, через точку, obj.method и является, по сути, посылкой сообщения объекту.

Третий пример:

(define stack
  (let ((vals '()))
    (define (pop)
      (if (empty? vals)
          (error "cannot pop from an empty stack")
        (let ((val (car vals)))
          (set! vals (cdr vals))
          val)))
    (define (push val)
      (set! vals (cons val vals)))
    (define (peek)
      (if (empty? vals)
          (error "cannot peek from an empty stack")
        (car vals)))
    (lambda (cmd . args)
       (case cmd
         ((pop) (pop))
         ((push) (push (car args)))
         ((peek) (peek))
         (else (error "invalid command")))))) 

(stack 'push 1)
(stack 'push 2)
(stack 'pop)
2
(stack 'peek)
1
(stack 'pop)
1
(stack 'pop)
; cannot pop from an empty stack

аналогично:

data StackMethod = Pop | Push | Peek

stack = dispatch <$> new []
  where
    dispatch x Pop _  = get x >>= (x =~ tail >>) . return . head
    dispatch x Push y = x =~ (y :) >> return y
    dispatch x Peek _ = head <$> get x

и пример:

stk <- stack :: IO (StackMethod -> Int -> IO Int)
                    -- stack это параметрически-полиморфный класс, в данном
                    -- случае берётся его спецификация когда элементы стека
                    -- имеют тип Int (можно взять что-то более общее).
                    -- Этот специфичный класс инстанцируется объектом stk.
mapM_ (stk Push) [1, 2, 3]
                    -- (stk Push) это применение метода Push на объекте stk,
                    -- с помощью ФВП mapM_ оно производится для всех элементов
                    -- списка.
repeat 4 $ stk Pop __ >>= print
                    -- 4 раза вызывается метод Pop, элементы печатаются.
                    -- Последний раз вызывается исключение (так как стек пуст).
3
2
1
*** Exception: Prelude.head: empty list

тут точно так же — в StackMethod перечислены нужные методы для стека, функция stack определяет класс, то есть объединение данных и функций с нужным поведением, она имеет тип IO (StackMethod -> a -> IO a), то есть принимает метод, элемент стека и возвращает элемент стека (в IO, мутабельно), сама функция в IO (вся структура данных ведёт себя мутабельно).

Дальше в OOPLAI начинают использовать макросы для придания более удобоваримого вида этим конструкциям. В настоящем (ну, _настоящем_ :)) ФП этого не нужно — примитивные ООП конструкции объединяющие данные и функции выглядят естественно и так, и являются частным случаем использования ФВП, IO и ADT с паттерн-матчингом (последние два — для удобства). Использование макро-системы может иметь смысл разве что если действительно нужно реализовать сложную ООП систему (например, со множественным наследованием и изменяемой иерархией классов, впрочем, обойтись одними функциями тут тоже можно, просто придётся делать больше механических действий).

Ещё пример:

-- | Данные — конструктор и аккессоры.
data Point = Point
  { x :: Double
  , y :: Double
  } deriving ( Show, Eq ) -- ad-hoc перегруженные функции.

-- | Методы привязываемые к данным (это уже _не_ ad-hoc перегруженные функции).
data PointMethod = Pos | Mov

-- | Класс (= функция), объединяющий данные и методы.
pointClass :: Double -> Double -> IO (PointMethod -> Double -> Double -> IO Point)
pointClass initX initY = dispatch <$> new (Point initX initY)
  where
    -- | (Динамический) диспетчер по методам. Он принимает объект (Var Point),
    -- имя метода (PointMethod, т.е. статическое, в данном случае, сообщение)
    -- и два опционных аргумента для методов (Double -> Double). Эту функцию
    -- можно помещать непосредственно в Point.
    dispatch :: Var Point -> PointMethod -> Double -> Double -> IO Point
    dispatch obj Pos _ _ = get obj
    dispatch obj Mov x y = obj =: Point x y
pnt <- pointClass 2 4         -- Инстанцирование класса pointClass объектом pnt
                              -- с начальными значениями полей 2 и 4.
:t pnt
pnt :: PointMethod -> Double -> Double -> IO Point
pnt Pos __ __                 -- Вызов метода Pos на объекте pnt.
Point {x = 2.0, y = 4.0}
pnt Mov 3 5                   -- Вызов метода Mov.
Point {x = 3.0, y = 5.0}
pnt Pos __ __                 -- Положение изменилось:
{x = 3.0, y = 5.0}

Нужно заметить, что это всё довольно примитивные конструкции (простые функции и IO). В случае использования ADT для имён методов получится динамическая диспетчеризация с фиксированным набором методов (well-typed), если же переписать функцию dispatch с завязкой на хэш-табличку (которая должна быть переменной в данных класса), то будет динамическая диспетчеризация с пополняемым набором методов и перегруженными методами (одни и те же сообщения можно посылать разным инстанцированным объектам, их dispatch будет их искать в хэш-таблице и обрабатывать, это уже ill-typed, то есть с исключениями вида «нет такого метода»). Разные прочие вещи вроде наследования и self точно также можно изобразить (аггрегация данных, представление иерархии классов в данных (в переменной или нет, в зависимости от возможности менять иерархию) и более сложная функция dispatch), но как-то не интересно.

P.S.

Код на хаскеле использует такие упрощения:

import Prelude hiding ( repeat )
import Data.IORef
import Control.Applicative
import Control.Monad

type Var a = IORef a

new :: a -> IO (IORef a)
new = newIORef

get :: IORef a -> IO a
get = readIORef

(=~) :: IORef a -> (a -> a) -> IO a
x =~ f = modifyIORef x f >> get x

(=:) :: IORef a -> a -> IO a
x =: x' = x =~ const x'

repeat :: Monad m => Int -> m a -> m ()
repeat = replicateM_

__ :: a
__ = undefined

P.P.S.

OOP / ООП в контексте данного поста — объектно-ориентированное программирование в духе объединения данных и процедур, то есть в духе C++, Java, Python и т.п. _Не_ ООП в духе классы = структуры, методы = перегруженные функции, наследование = схемы агрегаций и распространения методов (как это в CLOS и классах типов Haskell).

 , ,

quasimoto
()

Нужна годная литература по экономике

Форум — Talks

Добра всем.
Недавно пришло осознание, что в этой отрасли ничего не смыслю и что такое положение вещей совершенно никуда не годится, и поэтому озадачился найти что-либо из литературы на эту тему.
Однако погуглив я впал в лёгкое уныние - авторов куча, названий куча, ничерта не понятно, написано у них без живых примеров и настолько заунывно, что моментом клонит в сон.
Словом, буду признателен, если посоветуете что-то легкочитабельное (доскональное знание мелочей не нужно) для новичка в этой сфере, ведь наверняка кто-то сталкивался с подобным вопросом.

ffomg
()

Чем так хороши макросы в Lisp?

Форум — Development

Уже много всякого прочитал про лисп(в том числе Practical Common Lisp и уже даже освоился с Clojure), но никак не могу понять, чем же на самом деле являются макросы в этом языке. И этот вопрос не дает мне покоя т.к. лисп сильно повлиял на мое мышление и я вижу, что лисп (а особенно, common lisp для своего времени), действительно, лучше и удобней других языков (ну, за исключением странного скобочного синтаксиса ^^) ... Если бы его преимущества заключались в динамической типизации, сборке мусора и интерактивном цикле разработки, то их в полной мере имели бы питон, javascript и даже php.

Обычно пишут, что макросы - сильная сторона лиспа, которая отличает его от других языков и в качестве аргументов приводят неудачные примеры, которые довольно просто реализовать в других языках. Может кто-нибудь объяснить более-менее формально, что такое макросы? В чем их преимущества?

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

макрос выполняется до исполнения кода; вычислением аргументов макроса управляет программист.

Первое мне видится ограничением, которое приводит к целому ряду неудобств, как, например, невозможность применить apply к макросу(особено часто хочится сделать (apply and ...) или (reduce and ...)).

А второе может быть легко реализовано посредством функций высшего порядка хоть в C и C++. Для примера, в весьма популярной книге «Приемы объектно-ориентированного проектирования. Паттерны проектирования» Э. Гамма, Р. Хелм, Р. Джонсон, Д.Влиссидес описываются пaттерны Command и Interpreter - в комбинации это в точности макросы времени выполнения...

 

CheKastro
()

поделитесь кто и где нашел себе девушку?

Форум — Talks

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

 ,

cvv
()

Лучший способ выучить английский?

Форум — Talks

Сабж. Я пробовал по учебникам, если честно — не очень помогает. По себе чувствую, что с момента появления интернета (где без английского никуда) английский сам собой выучился на «интуитивном» уровне (т.е. не вспоминаешь, как сюда герундий или партисипл 2 сунуть, а просто сам как-то текст рождается) лучше, чем за все прочитанные до этого учебники.

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

Прошу отвечать тех, у кого был *личный опыт*.

paxac
()

[ФП][LISP] С чего начать?

Форум — Development

Недавно узнал, что на нашей специальности ФП преподавать не будут. Считаю это крайне неверным ходом, по-этому хочу взять всё в свои руки.

С чего лучше всего начать изучать ФП (с нуля)? Думается, что для общего развития будет полезно осилить LISP.

PS На других языках программировал, матан сдавал :)

 

helios
()

Посоветуйте задачек

Форум — Development

Посоветуйте хороший сборник (олимпиадных) задач по программированию. Приветствуются задачи уровня для новичков и выше. Спасибо. //**С выпавшим годным снегом в локации Беларусь! **На правах оффтопа

 , , , ,

int13h
()

Знание об архитектуре компьютера

Форум — Development

Какие нужны знания об архитектуре компьютера для изучения ассемблера? Желательно ответ в виде терминов, ссылок на статьи/книги.

 ,

VadimAlexeev
()

[ФП] Примеры работы с БОЛЬШИМИ файлами

Форум — Development

Всем привет, хочу продолжить тему работы с файлами в ФП. Тут недавно были примеры, но очень тривиальные, прочитать-записать. Вопрос такой, как в ФП-языке считать в память огромный файл как двумерный массив, и чтобы он а) занимал в памяти столько же места сколько на диске б) доступ к элементам был быстрый (О(1))?

Предистория такова, мы обрабатываем изображения с телескопов, там счёт идёт на сотни мегапикселей, и глубина пикселя 32 бита. Так что типичное изображение ~ два с половиной гигабайта, для этих целей специально собраны счётные узлы с 4 Гб RAM. Это чтобы изображение поместилось целиком в память, и оставалось на промежуточные буферы для накопления результатов. Естественно, все рассчёты написаны на Си и С++, работает быстро, памети хватает. Но код некрасивый, много повторяющихся конструкций и т.п. Народ в основном закостенелый из старшего поколения, ничего кроме Си и фортрана не знают, а я хочу попробывать более современные языки.

Так что буду благодарен за примеры чтения массивов для Haskell и особенно Scheme. И чтобы можно было посмотреть, сколько памяти реально израсходовано. Спасибо!

Ignatik
()

Прокачать математические способности

Форум — Talks

Кастую математиков и физиков в этот тред.

В свое время (еще в школе) математику я знал с натяжкой на тройку. Скорее всего виной этому были отвратительные учителя с самого начала обучения, да и что тут говорить - направленность школы была иной: я учил испанский, английский и французский языки. Математика естественно задвигалась подальше. Но чувствую явную потребность развить математические способности и ищу годного совета как это сделать и с чего начать.

Уверен, что это можно сделать, но надо понять как подступиться к задаче. И да, не надо устраивать наброс г-на на вентилятор, толку в этом мало. Всем, кто хоть что-то дельное посоветует: два чая и огромное спасибо.

 ,

Quadmonster
()

*values

Форум — Development

Сначала коротко для тех, кто произносит C++ как «Си с классами»

  • An lvalue - привязка value к функции или объекту. (Например: если E - это pointer type expression, тогда *E - это lvalue экспрешшен, забинденный на объект или функцию, куда указывает E. Другой пример: результат вызова функции, тип результата(return_type) которой lvalue reference - это lvalue.)
  • xvalue (x значит что угодно больной фантазии) биндится к объекту, обычно в конце его жизни (так что ресурсы могут поехать (move), например). xvalue - результат определенных типов экспрешшенов, в которых есть rvalue references. (Например, результат вызова функции, тип результата которой rvalue reference - это xvalue).
  • glvalue («generalized» lvalue) == lvalue | xvalue.
  • rvalue - xvalue, временный объект или подобъект, или значение, не ассоциированное с объектом.
  • prvalue («pure» rvalue) - rvalue, такое что не xvalue. (Например, результат вызова фунции, чей тип результата не reference – это prvalue)

А теперь вопрос. Что это все значит, мать его?

Какой практический смысл имеет выделение glvalue и prvalue?

Объясните в каких местах правильно и кошерно использовать rvalue references (которые ref&&)?

Олсо, поясните за поехавшую семантику (move semantics) и семантику копирования. Вот что такое поехавшая семантика, если простыми словами? А то я втыкаю в стандарт, что отдельные слова значат - вроде понятно, а как объяснить это одной фразой? Как это юзать? Вы реально юзаете копи-конструкторы?

Короче, какие есть хорошие практики на эту тему. Как это заюзать, чтобы не получилось как на картинке: http://i.imgur.com/jmBUEjr.png

 

stevejobs
()

Cascadia Ruby Conf 2012 A Taste of Prolog by Aja Hammerly

Форум — Development

Я просто оставлю это здесь.

 

Anatolik
()

Какой путь необходимо проделать к теории категорий?

Форум — Talks

Привет, ЛОР!
Предположим, понравился мне Haskell. Предположим, более-менее я его понял. Начинал я его учить с надеждой, что пойму математику. Ан нет, язык как язык, просто подход необычный.
Поспрашивав людей, я получил ответ, что просто так теорию категорий не выучить. Кто-то сказал, что нужно знать топологию. Кто-то упомянул другие области. А что скажете вы?
Исходные данные: студент второго курса какого-то шаражного вуза, непонятно как ещё не вылетевший. Практически полностью не понимаю матан, чуть лучше дела обстоят с линейной алгеброй и дискреткой, хотя тоже весьма плохо. Да, я тупой. Или ленивый. Или всё сразу. Но хочется исправиться.
Цель: понять теорию категорий и, желательно, применение оной. Ещё желательно было бы изучить как можно больше сфер математики, но это так, мечты.
Что скажете? Какую шикарную литературу по математике вы в своей жизни встречали? Нет ли какой-то волшебной книги по математике, которая охватывала бы все сферы?

 

Deleted
()

Чем сейчас лямбда выражения удобны?

Форум — Development

Что их наличие преподносится как большой плюс?

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

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

И если лямбда выражения используются только 1 раз в коде (а это преподносится как один из их плюсов - зачем городить целую функцию, когда только 1 раз это и пригодится), то чем это лучше

.....

T result;
{
// а вот тут код, который любят в лямбда функции совать
....
result = ....;
}
....

Перемещено JB из talks

cvs-255
()

ооп и функциональщина кратко, внятно.

Форум — Development

Дабы не слать напраслину на любителей создавать классы и объекты, пытаюсь разобраться в плюсах, которые отличаются от родителя, на первый взгляд, только названиями файлов, функций и приемами организации мышления погромиста. Так вот, эти ваши классы даже в учебнике называют почти структурами, а мизерное отличие сомнительного профита легко можно решить и в анси си(далее - ансися) при ближайшем обновлении. Ансися страдает перегрузкой названий функций для каждого из подлежащих обработке типов, отсутствием удобной иногда перегрузки функций, что, конечно минус, но не критично, ибо решаемо. Сиплюсик конечно удобен школьникам, тяжело принимающим всякие %s %d %x и так далее в качестве аргументов принтфов и сканфов, но зачем создавать для этого отдельный язык? Ведь << и >> становится лишним препятствием при освоении, если параллельно сдвиги битов читать. Итого, я вывел для себя, что в попытке облегчить участь программиста, разработчики языка усложнили его до степени родителя, не получив особенного профита. Чем же ооп так всем нравится, если оно не облегчает код?

 , , ,

minakov
()

а в вашем любимом ЯП есть что-то подобное?

Форум — Talks

Прекрасное введение в линзы, отличная статья, с подробными примерами и интересным оформлением, в отличии от скучных статей про монады. Заодно показывает суть хабра:

http://habrahabr.ru/post/189712/

а в вашем любимом ЯП такое есть?

затравка для Ъ:

«Если ты хочешь использовать композицию функций, где фунция имеет два аргумента», говорит Шерлок, «тебе нужно (.).(.)!”» «Это похоже на испуганную сову», восклицает Ватсон

Мы так близки к линзам! «Ммм я почти общущаю вкус линз Ватсон» расплывается от счастья Шерлок. «Линзы позволяют тебе выполнять композицию функций, fold и обходы (traversals) вместе. Я чувствую как функторы и fold -ы перемешиваются во рту прямо сейчас!»

 ,

qnikst
()

как это делается правильно ?

Форум — Development
wah :: Int -> IO ()
wah count = do rnds <- sequence $ replicate count $ randomRIO (0, 59)
               time <- getZonedTime
               let times = map (loctime $ zonedTimeToLocalTime time) rnds
               costs <- sequence $ replicate count $ randomRIO (100, 200 :: Int)
               volumes <- sequence $ replicate count $ randomRIO (10, 20)
               let candles = map (\(t, c, v) -> (Tick t c v)) $ zip3 times costs volumes
               let cnd = mconcat candles
               putStrLn $ fromMaybe "Undefined" $ getCandleColor cnd >>= return . show
               putStrLn $ "open is " ++ (show $ candleOpenCost cnd)
  where
(zonedTimeToLocalTime time) rnd}
    loctime :: LocalTime -> Int -> LocalTime
    loctime time rnd = time {localTimeOfDay = tofday (localTimeOfDay time) rnd}
    tofday :: TimeOfDay -> Int -> TimeOfDay
    tofday time rnd = time {todSec = topico rnd}
    topico :: Int -> Pico
    topico val = (toEnum val * (fromInteger $ resolution $ ((toEnum val) :: Pico)))

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

Есть такая фишка в хаскеле можно писать

..... = var {something = newvalue}
и это выражение вернет ту же структуру только с подставленным значением в указанное поле. А как подобное сделать для вложенных структур ? сейчас сделано извращение в where блоке, но сдается мне это не правильно.

PS:: особо доставляет функция topico которая «правильно» преобразует Int в Pico умножая его на размерность Pico (простой toEnum возвращает милиардные доли секунды, правильный хаскель такое правильный).

 expression,

s9gf4ult
()

Зачем нужна теория категорий?

Форум — Talks

Зачем нужен теоркат, если есть теория множеств?
И главный вопрос: в чем разница между категорией и множеством?

 ,

nerdogeek
()