Programowanie funkcyjne

0

Witam,

Wie ktoś może o jakimś poradniku dotyczącym programowania funkcyjnego? Nie chodzi mi o podręcznik do języka funkcyjnego - nauczenie się podstaw języka to nie problem. Problemem jest to że chyba za bardzo przyrosłem do programowania imperatywnego :/ Piszę program w LISP-ie, po czym zauważam (albo wydaje mi się że zauważam) że właściwie to, zmieniając jedynie składnie i słowa kluczowe, można przepisać źródła do, np, C++.
Jest jakiś sposób żeby naprawdę zacząć pisać kod funkcyjny?

PS. A może to wina programów które pisze? Piszę programy ze Spoja (który IMO aż roi się od zadań wymagających myślenia typowo imperatywnego ukierunkowanego na C/C++ - ale co ja tam wiem, być może po prostu nie widzę miejsc gdzie kod funkcyjny byłby idealny), bo nie mam pomysłów na proste programy, a za słabo znam język żeby napisać coś naprawdę użytecznego.

PPS. Czasami mi się w sumie udaje - z rozwiązania "Problemu Collatza" albo "parzyste" jestem w sumie zadowolony. Ale to raczej wyjątki

PPPS. Co ciekawe, nie mam problemów z pisaniem w Prologu który z imperatywnością ma tyle wspólnego co... nie ma nic wspólnego.

0

Type Theory and Functional Programming - podstawy teoretyczne. The Implementation of Functional Programming Languages, teoria i wpływ na implementację. Przede wszystkim musisz sobie wyrobić odpowiedni sposób myślenia, nabrać dystansu do kodu. Jeżeli nie piszesz w LISP-ie tylko Scheme (to jest rozróżniane) to regularnie przeze mnie polecane Structure and Interpretation of Computer Programs, dosyć łagodnie wprowadza w tworzenie abstrakcji, tak ważne przy programowaniu funkcyjnym.

BTW, pokaż trochę tych zabawek pisanych w LISP-ie co można bezpośrednio przełożyć na C, pomyślimy co z tym można zrobić...

0

Zaczynałem pisać w Scheme, teraz trochę bardziej w LISP-ie. W sumie SICP mam od jakiegoś czasu w zakładkach przeglądarki, nie wiem czemu jeszcze nie przeczytałem. Dwie pozostałe też wyglądają ciekawie chociaż są bardziej 'techniczne'.

Z tych cudów w LISP-ie które mi nie wyszły 'najlepsze' niestety (?) nie dostąpiły zaszczytu zapisania na twardym dysku i znikły zaraz po otrzymaniu AC.
Tym niemniej nieszczególnie piękne jest np. (podzielność) https://pl.spoj.pl/problems/PP0601B/

(defun listing (num max x y)
  (if (> num max) (return))
  (if (!= (mod num y) 0)
      (display num))
  (listing (+ num x) y max))

(defun read-eval (count)
  (if (<= count 0) (return))
  (listing 0 (read) (read) (read))
  (read-eval (- count 1)))

(read-eval (read))

Albo jeszcze lepiej, pesel (w Scheme) https://pl.spoj.pl/problems/JPESEL/
(chociaż nie wiem czy da się to znacząco poprawić z powodu specyfiki zadania)

(define (for-to curr max what)
  (if (< curr max)
    (begin
      (what)
      (for-to (+ curr 1) max what))))

(define (check-pesel pesel)
  (let
      ((n1  (* (modulo(quotient pesel 10000000000) 10) 1))
       (n2  (* (modulo(quotient pesel 1000000000 ) 10) 3))
       (n3  (* (modulo(quotient pesel 100000000  ) 10) 7))
       (n4  (* (modulo(quotient pesel 10000000   ) 10) 9))
       (n5  (* (modulo(quotient pesel 1000000    ) 10) 1))
       (n6  (* (modulo(quotient pesel 100000     ) 10) 3))
       (n7  (* (modulo(quotient pesel 10000      ) 10) 7))
       (n8  (* (modulo(quotient pesel 1000       ) 10) 9))
       (n9  (* (modulo(quotient pesel 100        ) 10) 1))
       (n10 (* (modulo(quotient pesel 10         ) 10) 3))
       (n11 (* (modulo(quotient pesel 1          ) 10) 1)))
    (modulo (+ n1 n2 n3 n4 n5 n6 n7 n8 n9 n10 n11) 10)))

(define (ensure-valid-pesel)
  (define pesel (read))
  (if (= (check-pesel pesel) 0)
      (display "D")
      (display "N"))
  (newline))

(define test-ct (read))

(for-to 0 test-ct ensure-valid-pesel)

PS. kolorowanie składni dla scheme nie działa...

0

No pierwsze może piękne nie jest, ale jakiś poziom trzyma. Drugie natomiast niepotrzebnie tak rozpisujesz, od czego wzięła się nazwa LISP? LISt Processing. Weź to zrób na liście, w końcu to operacje na ciągu wartości?

0

Rozwiązania w Scali:
http://www.ideone.com/spYXf
http://www.ideone.com/q2aiF

Na listach. Szczególnie piękne nie są, ale można je przerobić łatwo na LISPa czy inne funkcyjne.

0

Chyba dalej ZEN mi się nie udało osiągnąć, ale myślę że jest trochę lepiej (dzięki Wibowitowi od którego bezczelnie zerżnąłem pomysł :P i niezbyt udanie wprowadziłem w życie)

(defun sum (pesel)
  (let (
        (result 0)
        (ndx 0)
        (pesstr (format nil "~a" pesel)))
    (dolist (item '(1 3 7 9 1 3 7 9 1 3 1))
      (setf result (+ result (* (- (char-int (char pesstr ndx)) 48) item)))
      (setf ndx (+ ndx 1)))
    (print result)
    result))

Tak, wiem, za (setf result (+ result (* (- (char-int (char pesstr ndx)) 48) item))) powinienem trafić na theDailyWtf. Ale te i inne drobne niedoskonałości są raczej wynikiem mojej nieznajomości języka i jego ficzerów.

Dzięki wszystkim (tzn. deus i don... wibowit) za pomoc, może coś będzie z tego mojego programowania funkcyjnego :D

1 użytkowników online, w tym zalogowanych: 0, gości: 1