środa, 14 sierpnia 2013

Funkcje na poziomie typów

Haskell posiada wiele rozszerzeń zaimplementowanych w GHC. Jednym z najbardziej znaczących okazało się Functional Dependecies[1], które odmieniło życie wielu programistom Haskella. Niektórzy jednak narzekali, że nie jest to zbyt funkcyjne podejście i w końcu powstało inne bardziej funkcyjne. Mianowicie TypeFamilies[2]. Nie chcę tu opisywać na czym polegają funkcyjne zależności i tym bardziej jak to samo wyrazić za pomocą "rodzin typów". To o czym chcę dzisiaj napisać to to co dodatkowo umożliwiają rodziny typów czyli funkcje na poziomie typów (Type Level Functions).

O co chodzi

Funkcje na poziomie typów to takie funkcje, które wykonuje kompilator, a ich treść zapisana jest w typie. Brzmi to trochę zawile więc najlepiej będzie pokazać to na przykładzie. Zaczniemy od końca. Powiedzmy, że chciałbym aby moja funkcja mogła zostać wywołana tylko na argumencie, którego największy wspólny dzielnik (NWD czy też GCD) z liczbą 4 to 4. Próba wywołania jej na innym argumencie powinna skończyć się paniką kompilatora :)

fun :: (Nat a, GCD Zero a Four ~ Four) => a -> Int

Właśnie tak będzie wyglądać typ naszej funkcji. Wyjaśnienie:

  • Nat a - a jest liczbą naturalną, treść klasy Nat pokażę niżej,
  • GCD Zero a Four - typ GCD składa się z 3 parametrów: GCD r a b oznacza: reszta z dzielenia(r), pierwszej liczby(a) z drugą(b),
  • i wreszcie ~ Four - odpowiednik = w typach, innymi słowy GCD 0 a 4 = 4 czyli największy wspólny dzielnik liczby a i 4 to 4.

Liczby naturalne

Zaczniemy od zdefiniowania liczb naturalnych:



Zero zaskakująco oznacza 0. Natomiast Succ n oznacza kolejną liczbę po n czyli Succ Zero oznacza 1. Ciężko byłoby nam definiować większe liczby więc dla wygody zdefiniowane są dodatkowe typy jak One, Two, Four itd.

Klasa Nat reprezentuje liczby naturalne i zawiera funkcję toInt konwertującą liczbę naturalną do Inta. Godna uwagi jest implementacja toInt dla Succ n. Otóż wynika ona z tego, że nie posiadamy konstruktorów ani typu Zero ani też Succ n. Wykorzystujemy więc specjalną zmienną undefined, która może udawać dowolny typ i rzutujemy ją na typ n wewnątrz Succ, który musi być klasy Nat. Aby w ogóle móc w ten sposób zaimplementować tę funkcję potrzebne jest rozszerzenie ScopedTypeVariables[3], czyli najlepiej dodać sobie w pliku taką linijkę:

{-# LANGUAGE ScopedTypeVariables #-}

Możemy przetestować sobie w ghci to co do tej pory napisaliśmy:

> toInt (undefined::Four)
4

Type Families

Przyszła pora na zdefiniowanie naszej funkcji liczącej GCD. Funkcja będzie oczywiście realizowana na poziomie typów danych i do tego celu użyjemy rozszerzenia TypeFamilies więc od razu dodajmy sobie na początek pliku:

{-# LANGUAGE TypeFamilies #-}

Przejdźmy zatem do kodu:

Jeżeli ktoś nie widział nigdy wcześniej tego rozszerzenia to może go zaskoczyć słowo instance. To słowo kluczowe przede wszystkim sugeruje, że rodziny typów są otwarte tak samo jak klasy. Oznacza to, że ich "instancje" mogą być rozrzucone po plikach i zawsze można dołożyć kolejne. W przeciwieństwie chociażby do funkcji, która w całości musi być zdefiniowana w jednym pliku.

I co my tu mamy? Rekursywnie zaimplementowany algorytm liczenia największego wspólnego dzielnika. Mamy 3 warunki brzegowe:

  • gdy reszta z dzielenia to 0 i pierwszy argument to 0 to GCD Zero Zero a = a,
  • gdy reszta z dzielenia to 0 i drugi argument to 0 to GCD Zero a Zero = a
  • gdy dwie liczby zeszły do zera to GCD r Zero Zero = r,

No to sprawdźmy to od razu w GHCi:

> toInt (undefined::(GCD Zero Eight Four))
4

> toInt (undefined::(GCD Zero Eight Two))
2

Treść funkcji

Pozostało nam napisać testową funkcję, która przyjmuje tylko liczby podzielne przez 4 po czym je wypisuje. Wykorzystując typ funkcji z początku postu możemy napisać na przykład coś takiego:

fun :: (Nat a, GCD Zero a Four ~ Four) => a -> Int
fun a = toInt a

Spróbujmy zatem wywołać ja w GHCi:

> fun (undefined::Eight)
8

> fun (undefined::Six)
<interactive>:2:1:
    Couldn't match type `Zero' with `Two'
    Expected type: Four
      Actual type: GCD Zero Six Four
    In the expression: fun (undefined :: Six)
    In an equation for `it': it = fun (undefined :: Six)

Jak widać funkcja nie może zostać wywołana dla szóstki, gdyż nie jest podzielna przez 4 ale dla ósemki działa wyśmienicie.

Kiedy można to wykorzystać

Nie wykorzystamy tego na pewno dla argumentów podawanych dynamicznie, tj. z zewnętrznych źródeł jak baza danych, plik, klawiatura itd. Kompilator w żaden sposób nie sprawdzi czy liczba, którą wpiszemy podczas uruchamiania programu jest podzielna przez 4. No bo niby skąd on ma wiedzieć co wpiszemy?

Ale możemy to wykorzystać przy argumentach podawanych na sztywno w kodzie źródłowym. Przypuśćmy, że mamy dwie funkcje. Jedna która działa na wszystkich liczbach i druga, która działa na podzielnych przez 4. Oczywiście argumenty przekazujemy na sztywno. Mamy dwa wyjścia, albo napisać dwa różne typy danych, tzn. liczby podzielne przez 4 i dowolne liczby, albo utworzyć tylko jeden typ danych tak jak w naszym przykładzie i użyć rodzin typów by móc wymusić na nich własności, których oczekujemy.

Podsumowanie

Haskell po raz kolejny wprowadza programowanie na wyższy poziom. Być może rodziny typów to nie jest rzecz, którą da się często wykorzystać (przynajmniej jeśli chodzi o funkcje na typach danych) ale można w ten sposób poradzić sobie z kilkoma problemami. Więcej o rodzinach typów można znaleźć tutaj. Pełen kod użyty w tym poście do podglądu tutaj.

poniedziałek, 3 czerwca 2013

Okradać czy nie okradać

Ostatnio pisałem o problemach jakie niesie ze sobą wspieranie konsumpcji przez rząd (oraz o błędach w rozumowaniu). Dzisiaj natomiast postaram się wykazać logiczne następstwa działań rządów wspierających konsumpcję oraz dla porównania, tych wspierających produkcję. Zdradzę od razu, że słynne "kto chce obniżać podatki w czasie kryzysu ten kłamie" jest całkowicie logiczne lecz, jak już pisałem, oparte na błędnych założeniach. Nic co opiera się na kradzieży nie może przecież prowadzić do wszechobecnego dobra, gdyż wówczas kradzież musiałaby nim również być.

Wspieranie konsumpcji

Rząd wierzący ślepo w konsumpcję musi się zastanowić w jaki sposób może zachęcić czy wręcz zmusić obywateli do większej konsumpcji. Może to zrobić na wiele sposobów ale postaram się pokazać te najbardziej powszechne.

1. Kontrola pieniądza

Przede wszystkim ludzie zaczną więcej konsumować jeżeli nie będzie opłacało się oszczędzać. Stanie się tak np. wtedy, gdy każda złotówka, którą ludzie zarobią po jakimś czasie zmniejszy swoją wartość. Na przykład, jeżeli zarobię dziś 100 zł to jedyne co mnie powstrzyma przed trzymaniem ich w skarpecie to fakt, że za miesiąc kupię za nie tyle co dzisiaj za 90 zł. Czyli gdy ze 100 zł zrobi się 90. Ale jak to osiągnąć? Sprawa jest prosta. Wystarczy, że zwiększy się podaż pieniądza, gdyż wartość pieniądza, tak jak każdego dobra na rynku, kształtuje podaż i popyt. Jak wiadomo gdy rośnie podaż to spadają ceny. W tym celu tworzymy narodowy bank centralny, który będzie posiadał maszyny drukarskie aby móc fizycznie zwiększać podaż pieniądza zgodnie z wolą rządu. Jednak aby tego dokonać musimy jeszcze zadbać o to by w całym kraju można było płacić tylko tym pieniądzem emitowanym przez bank centralny. Jeżeli rząd by tego nie dokonał to ludzie widząc, że papier nie trzyma wartości woleliby płacić czymś, np. srebrem, złotem (czy nawet papierosami).

Czy to wystarczy? Jak już pisałem poprzednio, rozdanie ludziom po prostu dodatkowych pieniędzy spowoduje nagły wzrost cen więc skończyłoby się to tym, że ludzie wszystkie zarobione pieniądze wydawaliby na najbardziej przyziemne potrzeby. Cóż więc można zrobić? Należy stopniowo rozdawać pieniądze i to konkretnym małym grupom ludzi, którzy wykorzystają je na ważne, w mniemaniu rządu oczywiście, inwestycje.

2. Kontrola stóp procentowych

Rząd może rozdawać pieniądze ale niezbyt często i tylko niektórym podmiotom. To może nie wystarczyć (a kiedy wreszcie wystarczy?) więc należy zadbać o to, by również zwykli zjadacze chleba mogli kupować dobra wyższego rzędu bez potrzeby oszczędzania (gdyż podczas oszczędzania gospodarka się nie rozwija). W jaki inny sposób niż oszczędzanie można coś kupić na co się nie ma pieniędzy? Oczywiście biorąc kredyt. Jak wiemy banki nie chętnie rozdają kredyty osobom, które nie mogą ich spłacić. Władza musi więc zadbać o dwie rzeczy. Po pierwsze musi zmusić banki do rozdawania kredytów po określonym oprocentowaniu oraz aby tego dokonać musi im zagwarantować, że nie upadną.

Z czego banki udzielają kredytów? Uczciwie? Z pieniędzy, które wpłacają klienci i, co do których udzielają zgody na pożyczanie ich przez bank w zamian za część zysków. Niestety w ten sposób nie powstaje za wiele kredytów. Idealnie byłoby tak sprawić aby każdy pieniądz wpłacony do banku mógł być pożyczany. Jednakże wówczas wystarczy, że klienci nagle zechcą wypłacić wszystkie swoje pieniądze (tzw. run na bank), a bank nie będzie miał po prostu z czego oddać. Taki system nazywa się ładnie systemem o rezerwie cząstkowej, a mówiąc prościej piramidą finansową, w której to tylko część wpłaconych pieniędzy pozostaje w banku. Ta część nie może pozostać bez kontroli (w Polsce wynosi 3,5%). Ale jak zabezpieczyć banki przed ich upadkiem w przypadku runu? Nie można dopuścić by bankowi zabrakło pieniędzy więc musi powstać odpowiedni fundusz, na który będą się zrzucały wszystkie banki (czyli de facto ich klienci) i w razie czego będzie można tym je uratować. Jeżeli to nie wystarczy to są przecież jeszcze maszyny drukarskie. Oprocentowanie kredytów kontroluje się za pomocą tzw. stóp procentowych czyli minimalnego oprocentowania kredytu, po którym bank udziela go swoim najlepszym klientom.

Warty odnotowania jest fakt, że jeżeli bank może pożyczać 96,5% wpłaconych pieniędzy to będzie chciał pożyczać je jak najtaniej bo przy takiej ilości środków najmniejszy procent będzie generował horrendalny zysk, a im mniejszy procent tym więcej pieniędzy uda się pożyczyć. Jak wiemy tanie kredyty spowodują natychmiastowy wzrost cen tak samo jak dodrukowanie pieniędzy (gdyż jest to właściwie to samo, ale to tym kiedy indziej). Co jest kryterium ustalania stóp procentowych? Oczywiście skala konsumpcji. Jeżeli eksperci uznają, że ludzie dużo konsumują to można te stopy utrzymywać na wyższym poziomie, a jeżeli za mało to trzeba je obniżyć. Oczywiście najlepiej tą odpowiedzialność zrzucić "na ekspertów" więc stopy procentowe w Polsce ustalają ekonomiści wchodzący w skład Rady Polityki Pieniężnej.

3. Podatki

Każdy rząd jest świadomy tego, że ludzie zazwyczaj są głupi i konsumują to co służy im egoistycznym pragnieniom. Ale przecież ktoś musi zadbać o wyższe cele takie jak badania naukowe, ochrona środowiska, utrzymywanie pokoju na świecie czy edukacji i służba zdrowia. Na te cele potrzeba by dodrukować sporo pieniędzy, a to odbiłoby się zbyt gwałtownym wzrostem cen. Co można innego zrobić? Oczywiście ukraść... tfu, opodatkować! Innymi słowy jak zabierze się ludziom pieniądze to ich przecież nie przybędzie i będzie można je wydać na rzeczy, na które oni nie chcą sami wydawać. W ten sposób rząd uchroni kluczowe dla niego firmy przed upadkiem, a nawet sprawi, że one nigdy nie będą musiały się troszczyć o klientów, gdyż pieniądze zawsze się dla nich znajdą. Czyli podatki utrzymuje się możliwie wysokie (aby mogły się rozwijać strategiczne dla państwa firmy). Szczególnie ważne jest to w czasie kryzysu kiedy ludzie, gdy czują, że ich posady są zagrożone, zaczynają szczególnie oszczędzać.

Rząd doskonale wie, że ludzie nie lubią płacić podatków i będą szukali schronienia czy to w innych krajach czy to ukrywając swoje dochody. Prawo zatem musi być skonstruowane tak aby takie działania były szczególnie piętnowane. Jednak aby wymusić stosowanie prawa, potrzebna jest kontrola policji i sądów. To rzecz najzupełniej oczywista. Ale samo zastraszenie ludzi nie wystarczy. Najlepiej byłoby sprawić by ludzie uznali podatki za coś dobrego, coś z czego czują, że odnoszą korzyści. Można oczywiście wybudować jakieś drogi, parki, rozdać trochę pieniędzy ubogim (tylko nie za dużo aby zostało coś na kluczowe firmy) ale to i tak nie wystarczy. Te barany zawsze liczą pieniądze i jak będą mieli przynieść połowę pensji do urzędu to oczywiście nikt nie przyjdzie, a to by oznaczało użycie siły. Jest lepszy sposób. Jak wiadomo ludzi, którzy dają pracę jest zdecydowanie mniej więc ich łatwiej będzie zastraszyć. Wystarczy aby to oni odprowadzali podatki za swoich pracowników. Czyli pracownik z pensji, którą otrzyma od pracodawcy już nic nie będzie musiał nic oddać. Ba, mało tego, jak rząd wprowadzi jeszcze ulgi podatkowe to będzie on (pracownik) miał wrażenie, że nie tylko nic nie płaci ale to jemu państwo dopłaca!

4. Kontrola konkurencji

Rozumiemy już, że szczególnie złym dla państwa zjawiskiem są zbyt szybko obniżające się ceny. Oczywiście zbyt szybko podnoszące się ceny też będą złe, gdyż nikt nie zdąży na nie zarobić, a ratowanie później gospodarki tanimi kredytami może się źle skończyć. Obniżające się ceny mogą skłonić ludzi do zwlekania z kupnem towaru, a więc do ograniczenia konsumpcji. Co jest oczywiście niedopuszczalne! Jak z tym walczyć? Jednym z czynników powodujących spadek cen jest rosnąca konkurencja. Z jednej strony konkurencyjne firmy mogą się dogadać między sobą (tzw. zmowa cenowa), a z drugiej może znaleźć się ktoś zbyt uzdolniony, kto wykona tę samą pracę połowę taniej. A co będzie jeśli po nim znowu znajdzie się ktoś kto wykona to jeszcze połowę taniej? Nie możemy do tego dopuścić. Najlepszy jest oczywiście złoty środek czyli ceny wśród konkurentów powinny oscylować wokół średniej. Gdy któraś firma wypada zbyt daleko od średniej (oczywiście gdy produkuje taniej, bo gdy drożej to i tak nikt tego nie kupi) to znak, że stosuje dumping cenowy (produkuje za tanio) co jest bardzo złe dla gospodarki. Przez nią mogą upaść pozostałe firmy produkujące drożej czyli znowu spadłaby konsumpcja. Tak jak w przypadku podatków rząd musi się skupiać na piętnowaniu firm, gdyż bez ich kontroli konsumpcja może całkowicie zaniknąć.

5. Inne regulacje

Jest jeszcze wiele innych zagadnień. Na przykład trzeba jakoś sprawić by z jednej strony firmy płaciły coraz więcej pracownikom by mogli coraz więcej konsumować (np. płaca minimalna, związki zawodowe), co znowu jest podwójnie dobre, gdyż pozbawia firmę tak złych oszczędności. Jak firma nie chce wydawać to niech zrobi to jej pracownik. A jeśli firma nie ma oszczędności? To trzeba ją poratować jakąś dotacją, sprawiając tym samym, że zaczyna ona dbać wówczas o to czego chce państwo, a nie o to czego chcą klienci. Państwo płaci, państwo wymaga. Z drugiej strony ważne jest by obywatel zawsze liczył na państwo, gdyż wtedy nie będzie próbował omijać podatków.

Podsumowanie

Jak widać niemal wszystkie działania rządu są całkowicie logicznym następstwem przesłanki, że wspieranie konsumpcji prowadzi do dobrobytu. Problem oczywiście w tym, że ta przesłanka jest błędna. Dla porównania zobaczmy co robiłby rząd, który wspiera (całkiem słusznie) produkcję.

Wspieranie produkcji

Czy rząd potrzebuje kontroli pieniądza do motywowania ludzi do działania? Dodrukowywać nie ma sensu, ponieważ w ten sposób pozbawia ludzi oszczędności, które są odkładane na inwestycje (czyli konsumpcję odłożoną w czasie). Jeżeli zabierze wszystkim tyle samo to nic to nie zmieni, gdyż zarówno ludzie będą mieli mniej pieniędzy jak i ceny spadną. Jeżeli zabierzemy niektórym to nie odłożą oni na inwestycje. Zatem kontrolowanie pieniądza nie ma sensu.

A stopy procentowe? Nie jest w interesie rządu narzucać rynkowi ceny kredytów, gdyż jeżeli nie trafi to znowu zabierze ludziom oszczędności lub zabierze ludziom kredyty, które w normalnej sytuacji nie są szkodliwe (tzn. wtedy gdy klient wie, że jego oszczędności są pożyczane i może je stracić), a nawet pożyteczne. Pożyteczne dlatego, że jeżeli ryzykant biorący kredyt wytworzy tyle dobra, że nie tylko go spłaci ale jeszcze coś dołoży to tylko możemy się cieszyć. Ale dlaczego nie są szkodliwe? Gdyż saldo się zgadza. Jak bank pożyczył pieniądze to mamy 0 na koncie, a nie jak poprzednio tyle samo co mieliśmy (czyli nie przybyło pieniądza do gospodarki). Jak bank będzie oszukiwał to rynek doprowadzi go w końcu do upadku. Jak klient nie spłaci to nic się nie stanie, bo klient banku liczył się z ryzykiem. Po prostu klient nie zaufa drugi raz temu bankowi, a bank następnym razem będzie bardziej uważny komu pożycza pieniądze.

Podatki? Każde opodatkowanie zmniejsza oszczędności czyli rząd musi starać się je utrzymywać możliwie najniższe (lub wcale).

Kontrola konkurencji? Rynek świetnie ją kontroluje. Firmy produkujące za drogo lub nieuczciwie są przez klientów omijane więc upadają. Nie ma kto ich ratować. Zatem wszystko pod kontrolą :)

Co innego można zrobić? Przede wszystkim musimy dbać o prawo własności oraz o rozwiązywanie konfliktów. Każda kradzież działa tak samo jak podatki (właściwie to to samo, nie?). Oczywiście można pozostawić tę sprawę rynkowi, a można ją też znacjonalizować. Nie wchodźmy tu wspór co jest lepsze.

Streszczenie

Poniżej to samo, w krótkiej formie:

WSPIERANIE KONSUMPCJIWSPIERANIE PRODUKCJI
kontrola pieniądza - jedna państwowa papierowa walutabrak kontroli pieniądza, wiele pieniędzy na rynku (w tym brak papierowych)
kontrola banków i stóp procentowychbrak kontroli banków i stóp procentowych
możliwie wysokie podatkimożliwie niskie podatki (lub ich brak)
kontrola konkurencji, dużo regulacji firmbrak kontroli, mało regulacji (lub w ogóle)
płaca minimalna, związki zawodowe, dotacje, socjal (by każdy mógł coraz więcej konsumować)oczywiście brak ingerencji państwa w życie obywateli, każdy jest odpowiedzialny za siebie


Podsumowując, wspieranie konsumpcji sprowadza się przede wszystkim do okradania obywateli. Ludzi traktuje się jak bydło, które nie wie co dla nich dobre. I to, jak mówią, dla naszego własnego dobra. Tym bardziej nie ma to sensu, gdy już wiemy, że to podaż tworzy popyt, a nie odwrotnie. Całe zagadnienie sprowadza się do tytułowego pytania okradać czy nie okradać.

Polecam bardzo książkę "Historia pisana pieniądzem" Jakuba Wozinskiego, która ukazuje losy Polski w kontekście pieniądza. Jak się zapewne spodziewasz każdy władca chciał mieć monetę w swoim ręku i zmuszał ludzi do posługiwania się nią. W ten sposób mógł bezkarnie okradać obywateli finansując swoje cele. Nic od tamtej pory niestety się nie zmieniło.

środa, 29 maja 2013

Czy konsumpcja jest dobra?

Dzisiaj piszę w oderwaniu od programowania, gdyż z pięknego snu od czasu do czasu wyrywa mnie ludzka ignorancja - tym razem ekonomiczna. Do programowania na pewno jeszcze powrócę lecz teraz czas wyjąć skrywaną broń i poruszyć sprawy największej wagi.

Otóż wiele naprawdę cenionych w Polsce osób twierdzi, że dzięki konsumpcji gospodarka się rozwija. Logicznym następstwem tej teorii jest negowanie posiadania oszczędności, gdyż jak to ujął pewien klasyk "pieniądze te raczej marnowałyby się na lokatach niż realnie pracowały w gospodarce". Skąd ten pomysł? Ano stąd, że jeśli kupujemy np. lizaka to firma, która go wyprodukowała dostaje za niego zapłatę, a więc sygnał, że lizak jest ludziom potrzebny i zaczyna produkować więcej. Zatem, jak twierdzą nasi bohaterowie, konsumpcja napędza produkcję. Im więcej kupujemy tym więcej będzie wytwarzane, czyli będzie więcej dóbr na rynku, a więc gospodarka się będzie rozwijać. Prawda, że proste?

Ale zaraz, zaraz. Dlaczego więc nie zmusić ludzi do wydawania wszystkiego co zarobią, a może nawet i jeszcze więcej? Przecież więcej konsumpcji = więcej dóbr = większy wzrost gospodarczy, czyż nie? Taki stan jest łatwo przecież osiągnąć (dla rządu), wystarczy tylko obniżyć stopy procentowe (do 0 albo jeszcze niżej) co spowoduje, że kredyty będą tanie jak barszcz. Wówczas lepiej będzie wziąć kredyt na powiedzmy milion złotych (bo będziemy musieli oddać tylko milion albo jeszcze mniej) niż oszczędzać mozolnie przez 20 lat.

No to mamy milion właściwie za darmo więc co? Kupujemy jacht? A co! Idziemy zatem do producenta i patrzymy, a tam ceny za jacht wynoszą nie milion, a 100 milionów. Ale jak to? Nie tylko my wzięliśmy ten kredyt ale wiele innych osób również skorzystało z okazji przed nami. Producent więc widząc gwałtownie rosnący popyt podwyższył cenę.

No to co, może chociaż mieszkanie? Powiedzmy, że jesteśmy jednymi z pierwszych, którzy chcą je kupić ale i tak teraz cena małego mieszkania wzrosła do miliona. Nie no miliona za małe mieszkanie to przecież nie damy! Nawet jeśli byśmy dali to i tak następni nie kupią go już po tej cenie. To przynajmniej zabawimy się trochę. Kupimy sobie trochę lodów, pójdziemy do kina i na łyżwy. Ceny tych dóbr również wzrosły (bo wzrósł popyt) ale nie aż tak bardzo więc za milion to trochę sobie poużywamy.

Widzimy więc, że większość konsumpcji zostaje ulokowana w bardzo przyziemnych dobrach. Skoro tak to napędziliśmy gospodarkę. Niestety nikt nie zainwestowałby tych pieniędzy w przemysł (np. kupując samochód, komputer, samolot czy płacąc za autostradę) bo by się nie opłacało (cena byłaby zbyt wysoka). Koniec końców nikt by tych kredytów już nie chciał brać, poniewż ceny rosłyby z godziny na godzinę. Ludzie w końcu przestaliby konsumować cokolwiek, gdyż aby to uczynić to wszystko co zarobią danego dnia musieliby migiem od razu wydać. Najlepszym pomysłem w takiej sytuacji byłoby po prostu samemu prowadzić gospodarstwo i zadbać sobie o jedzenie, wodę i wszystkie podstawowe potrzeby niż chodzić do pracy po pensję, którą moglibyśmy nie zdążyć skonsumować. Czyli w efekcie gospodarka zmieniła kierunek w produkcję przyziemnych dóbr po czym by padła, gdyż ludzie wrócili do własnych gospodarstw i przestali cokolwiek kupować.

Czyli co, konsumpcja jest zła? Zastanówmy się jak to wygląda, gdy rząd nie ingeruje w gospodarkę w ogóle. Naszym marzeniem jest jacht za milion złotych. Nie mamy takich pieniędzy i nie ma tanich kredytów. Pozostaje nam oszczędzanie i inwestowanie tych oszczędności. Ale skąd wziąć te oszczędności? Najpierw musimy coś wytworzyć co będzie wartościowe dla innych ludzi. Czy to w postaci naprawienia komuś kranu czy wyprodukowania samochodu - nie ma to większego znaczenia, co najwyżej uzyskamy mniej środków w zamian za pierwszą opcję. Później musimy ograniczyć konsumpcję aby nie wydać wszystkiego. Po jakimś czasie uzyskujemy odpowiednie oszczędności i możemy kupić jacht. Po prostu odłożyliśmy swoją konsumpcję w czasie aby kupić coś bardziej dla nas wartościowego. Wyszło więc na to, że produkując (np. naprawiając kran) wytworzyliśmy popyt (na jacht za milion).

No dobrze ale co jeśli wszyscy zaczną kupować lody za zaoszczędzone pieniądze? Gdyby tak się stało to wynikałoby to z faktycznych potrzeb tych ludzi w przeciwieństwie do poprzedniego przykładu gdzie po prostu nic innego nie dało się kupić. W ten sposób nie ma straty dla gospodarki, ponieważ rozwijamy te gałęzie gospodarki, które naprawdę są ludziom potrzebne.

Zatem twierdzę, że to produkcja prowadzi do dobrobytu, a nie konsumpcja. Odpowiadając na tytułowe pytanie to konsumpcja jest dobra o ile jest wydawana na towary, które w danej cenie faktycznie ludzie potrzebują. Innymi słowy konsumpcja jest dobra dla całej gospodarki jeżeli jest dobra dla jednostki. Nietrafione inwestycje powodują w dalszym czasie kryzysy (upadek firm inwestujących nietrafnie tworzy bezrobocie). Dobrym tego przykładem jest ostatni kryzys na rynku nieruchomości. Najpierw rząd (USA) powiedział bankom aby dawały kredyty każdemu kto chce kupić mieszkanie (nie zależnie czy będzie potrafił go spłacić). W razie nie spłacenia kredytu przez kredytobiorcę, miał go spłacić rząd. No to sielanka trwała, ceny nieruchomości nieustannie rosły (bo zwiększał się popyt), firmy budowlane rosły razem z nimi aż nagle rząd stwierdził, że nie będzie dalej spłacał dłużników. Co się stało? Zaczęły padać banki, firmy budowlane, a razem z nimi firmy produkujące dla tych firm oraz klienci tych banków. Cele ludzi się nie zmieniły (nadal chcą mieć własne mieszkanie), a mimo to firmy upadły. W przypadku oszczędności nie ma tego problemu bo jeśli chcemy mieć mieszkanie to na nie oszczędzamy czyli przede wszystkim skupiamy się na produkcji. Nikt nam nie zakręci kurka. Taki kryzys może wywołać jedynie masowa kradzież naszych oszczędności (Wielki Kryzys w Ameryce). Oczywiście czasami ludzie dochodzą do wniosku, że wytworzone dobro to jednak niewypał i zmieniają swoje cele co tworzy kryzys ale nie na taką skalę. Firmy produkujące niepotrzebne ludziom dobra (albo w nieodpowiednich dla ludzi cenach) powinny upadać! I im szybciej tym mniejszy kryzys. W tym przypadku błędną inwestycją była inwestycja banków w ludzi, którzy nie byli w stanie spłacić kredytu. A upadek był tak bolesny, ponieważ rząd go przedłużał płacąc za tych ludzi.

Na sam już koniec czy nie wydaje wam się naturalne, że ceny powinny raczej cały czas maleć aniżeli rosnąć? Przecież technologia cały czas idzie do przodu, wytwarza się więc coraz taniej, a mimo to ceny rosną. Związane jest to z naszym pierwszym przykładem, w którym najpierw rośnie popyt, a dopiero potem podaż. W normalnej sytuacji to najpierw rośnie podaż, który wytwarza popyt (prawo Saya). I znowu wiele osób uważa, że to źle, że ceny cały czas spadają, gdyż to prowadzi do spadku konsumpcji. Dlaczego?

Otóż wydaje im się, że jeśli wiesz, że dzisiaj mieszkanie kosztuje 400 tys. zł i za rok będzie kosztować 350 tys. zł to oczywiste jest, jak twierdzą, że wstrzymasz się z zakupem do przyszłego roku. Ale za rok będzie ta sama sytuacja, gdyż za dwa lata cena spadnie do 300 tys. zł więc w efekcie nigdy mieszkania nie kupisz.

Ciężko o większą bzdurę. Jeśli wszyscy będą się wstrzymywać z kupnem mieszkania to zmaleje popyt czyli cena nie będzie spadać, a rosnąć! Poza tym np. komputery na początku swej egzystencji kosztowały o wiele więcej niż kosztują teraz. Samochody zresztą również. I jakoś ludzie wtedy też je kupowali i kupują je nadal. Człowiek na szczęście nie sugeruje się tylko ceną za jaką chce coś kupić ale przede wszystkim chodzi mu o posiadanie. Co mi po tym, że być może za 60 lat kupie mieszkanie za 1000 zł jak do tego czasu nie będę miał gdzie mieszkać? :)

sobota, 23 marca 2013

Programowanie webowe w Haskellu cz. 3

Trochę ostatnio zaniedbałem bloga za co bardzo przepraszam. Dzisiaj tematem będą własne bardziej wyrafinowane znaczniki w szablonach. Postaramy się wykonać znacznik <if>, który będzie działał według poniższej koncepcji.

Koncepcja

Pomysł polega na tym aby w szablonie móc wpisać coś takiego:
<if>
<equal a="${name}" b="kogut"/>
<then><b>My name is kogut</b></then>
<else>My name is not kogut</else>
</if>
<if>
<not><equal a="${name}" b="kogucik"/></not>
<then><b>My name is not kogucik</b></then>
<else>My name is kogucik</else>
</if>


Wydaje mi się, że koncepcja jest w miarę jasna. Po prostu jeżeli w pierwszym ifie ${name} będzie równe "kogut" to na stronie pojawi się My name is kogut, a w przeciwnym razie "My name is not kogut". Drugi natomiast wyświetli My name is not kogucik jeżeli ${name} będzie różne od "kogucik". Inaczej dostaniemy "My name is kogucik".

Funkcja addSplices

Aby dodać znaczniki, które będą rozpoznawalne we wszystkich szablonach potrzebujemy użyć funkcji addSplices. Podobnie jak funkcja renderWithSplices przyjmuje on listę par ("nazwa znacznika", wartość). Tą wartością tym razem będzie specjalnie przez nas przygotowana funkcja analizująca nieco znaczniki wewnątrz naszego znacznika "if". Zatem dopisujemy w pliku Site.hs w funkcji app, gdzieś przed funkcją return taką oto treść:
addSplices [("if", ifSplice)]

Jako, że za chwilę utworzymy sobie nowy plik o nazwie Splices.hs to od razu możemy go tutaj zaimportować. W tym celu na górze pliku, w miejscu gdzie występują instrukcje import dopisujemy:
import Splices

Nowe znaczniki

Jak wspomniałem już wcześniej utwórzmy sobie plik o nazwie "Splices.hs". Jego treść, którą za chwilę omówię będzie wyglądać następująco:


Najważniejszą funkcją w tym pliku jest ifSplice. Działa ona następująco:
  • najpierw pobieramy wszystkie dzieci elementu "if", przetwarzając dodatkowo elementy "not" i "equal" (gdyby się one tam znalazły) odpowiednimi funkcjami - to realizuje właśnie funkcja runChildrenWith,
  • następnie sprawdzamy czy w ogóle jakieś dzieci występują (po podmianie znaczników "equal" i "not"),
  • jeżeli nie to wyświetlamy komunikat błędu,
  • w przeciwnym razie pobieramy pierwszy element wewnątrz "if" i sprawdzamy czy jest to zwyczajny tekst,
  • jeżeli nie to znów wyświetlamy komunikat błędu, gdyż oczekujemy, że pierwszy element będzie równy "1" lub "0",
  • jak już mamy tekst to sprawdzamy czy jest równy "1",
  • jak tak to wyszukujemy element "then" i wyświetlamy jego dzieci,
  • jeżeli tekst jest różny od "1" to szukamy elementu "else" i wyświetlamy jego zawartość.

Funkcja equalSplice jest bardzo prosta. Pobiera ona znacznik "equal" (za pomocą funkcji getParamNode, która zwraca aktualnie przetwarzany znacznik, a wiemy, że jest nim "equal") i sprawdza czy istnieją argumenty o nazwie "a" i "b". Jeżeli tak to porównuje ze sobą zawartość obu argumentów i jeżeli są równe to zwraca tekst "1", a jeżeli nie to "0".

Funkcja notSplice również jest prostą funkcją. Najpierw pobiera swoje dzieci. Później sprawdza czy jest to dokładnie jeden element i to tekstowy. Jeżeli jest on równy "1" to zwraca "0", w przeciwnym razie zwraca "1". Tak na marginesie, w szablonie znacznik <not> może mieć wiele dzieci. Chodzi o to aby po podmienieniu wszystkich znaczników wewnętrznych pozostał tylko jeden. Podmianę zdefiniowanych znaczników wewnątrz elementu "not" realizuje funkcja runChildren. Dlatego właśnie możemy w szablonie umieścić <not><equal ... /></not>.

W tym momencie możemy już skompilować naszą aplikację, umieścić odpowiednie znaczniki w szablonie (np. te pokazane w koncepcji), uruchomić ją i nacieszyć oczy. Spróbujcie sobie w ramach ćwiczenia dopisać znaczniki "lt" i "gt" zwracające "1" odpowiednio, gdy argument a < argument b oraz dla drugiego znacznika, gdy argument a > argument b. W kolejnej części zajmiemy się obsługą bazy danych. To do następnego razu i powodzenia!

czwartek, 31 stycznia 2013

Programowanie webowe w Haskellu cz. 2

Oto kolejna część poświęcona programowaniu webowemu w Haskellu. Postaram się w niej opisać dwie rzeczy, pierwsza to jak poradzić sobie z wieczną rekompilacją kodu i druga to system szablonów Heist. Zatem do dzieła!

Programowanie bez kompilowania

W snapie możliwe jest pisanie kodu bez ciągłego wywoływania cabal install (czy też cabal build) po każdej zmianie. Aby to umożliwić przechodzimy do katalogu z projektem i wywołujemy:
$ cabal clean ; cabal install -f development
To może zająć chwilę z uwagi na to, że możecie nie mieć odpowiednich bibliotek. Gdy się już przekompiluje to uruchamiamy nasz projekt tak jak ostatnio (czyli ./dist/build//) i w przeglądarce wpisujemy http://localhost:8000. Powinniśmy ujrzeć nasze "Hello world!". No to teraz niech nasz projekt sobie dalej działa, a my zmieńmy nieco plik Site.hs. Odnajdźmy linijkę writeText "<h1>Hello world!</h1>" i zamieńmy ją na writeText "<h1>Hello new world!</h1>" po czym zapiszmy plik. Gdy odświeżymy stronę zmiany powinny zostać naniesione.

Spróbujmy teraz wywołać błąd. Dopiszmy w tej samej linijce np. cyfrę 1, tylko, że za cudzysłowem. O tak: writeText "<h1>Hello new world!</h1>" 1 i odświeżmy stronę. Zamiast "Hello new world!" dostaliśmy szereg informacji o błędach w kodzie, jakie by nam wypisał kompilator podczas kompilacji.

W ten sposób programuje się nieco szybciej przy małych zmianach w kodzie. Interpretacja jednak bardzo spowalnia aplikację więc nie da się w ten sposób używać aplikacji w produkcji. Gdybyśmy chcieli teraz normalnie skompilować aplikację to znów należy wykonać najpierw cabal clean, a później cabal install już bez dodatkowej opcji.

Heist

Jak już wspominałem w pierwszej części artykułu programowanie za pomocą writeText byłoby bardzo uciążliwe i czasochłonne. Pokażę Wam zatem lepszy sposób na wyświetlanie HTMLa.

Heist jest systemem szablonów używanym w snapie. Pliki szablonów to zwyczajne pliki htmlowe (bądź xmlowe) z tą tylko różnicą, że Heist sprawdza poprawność tych plików przy uruchomieniu serwera (czyli czy są podomykane odpowiednie znaczniki itp.) oraz można utworzyć własne znaczniki, które Heist nam podmieni. Z tym, że nie muszą być to po prostu wartości, możemy np. utworzyć sobie własny znacznik <if>, który tylko, gdy podany warunek będzie spełniony to wyświetli to co jest pomiędzy znacznikiem otwierającym, a zamykającym itp. itd.

Pliki szablonów są trzymane w katalogu snaplets/heist/templates i muszą mieć rozszerzenie tpl. Utwórzmy tam plik hello.tpl o treści <h1>My first template</h1>. Teraz w naszej funkcji handleHelloWorld (w pliku Site.hs) wprowadzimy wyświetlenie tego szablonu. W tym celu usuwamy dotychczasową treść funkcji i wpisujemy: render "hello". Możemy odświeżyć stronę by zobaczyć efekt.

Funkcja render jako argument przyjmuje nazwę szablonu bez rozszerzenia i po prostu wyświetla szablon. Teraz spróbujmy wprowadzić jakiś własny znacznik do szablonu, np <name/>. Dodajmy go gdzieś w pliku szablonu i powróćmy do naszej funkcji handleHelloWorld. Zamieńmy jej treść na coś takiego:
renderWithSplices "hello" [("name", I.textSplice "Ala")]
Funkcja renderWithSplices różni się od funkcji render tym, że pozwala dodać własne znaczniki (technicznie nazywają to splice, dlatego właśnie renderWithSplices). Znaczniki dodaje się w parach (nazwa, wartość). Jeżeli chcemy dodać ich więcej to po prostu piszemy po przecinku kolejne pary w liście, np: renderWithSplices "hello" [("name", I.textSplice "Ala"), ("urodziny", I.textSplice "jutro")]. Funkcja textSplice tworzy znacznik, który jest po prostu tekstem (może być jeszcze innym znacznikiem lub komentarzem). Gdybyśmy podali jej jakiś tekst, który byłby kodem HTML to zmieniłby go tak aby się wyświetlił jako tekst, np. "<br>" nie wyświetliłby nowej linii lecz po prostu napis "<br>".

UWAGA: jeżeli w szablonie wpisalibyśmy coś takiego:
<h1 class="<name>">My first template</h1>
to oczywiście nie jest to poprawny kod HTMLa i Heist by zwrócił błąd. Jeżeli chcemy używać własnych znaczników w atrybutach należy użyć specjalnej składni:
<h1 class="${name}">My first template</h1>

To tyle na dziś. Następnym razem spróbujemy utworzyć ciekawsze znaczniki jak np. wspomniany wcześniej if. Do tego czasu postarajcie się dzisiejszą lekcję dobrze opanować.

poniedziałek, 14 stycznia 2013

Programowanie webowe w Haskellu cz. 1

Początkujący haskellowiec poszukując polskich stron dotyczących Haskella napotyka na poważny problem. Praktycznie nie ma nic sensownego na ten temat. Być może znajdzie informacje (jak będzie dobrze szukał) o tym jak stawiać pierwsze kroki w tym języku ale poważniejszych przykładów brak. Pewnie wynika to z tego, że programistów Haskella w Polsce nie ma zbyt wielu, a ci którzy są raczej nie wiele publikują. Właśnie z tego powodu postanowiłem napisać krótki kurs programowania stron internetowych. Nie będzie on specjalnie trudny ale jednak aby go zrozumieć będzie wymagana pewna podstawowa wiedza, którą można zdobyć np. tu.

W Haskellu mamy do wyboru dwa podejścia do tworzenia stron. Pierwsze jest podobne do tego w PHP, pythonie, rubym itd. czyli wywoływanie programów przez serwer HTTP dzięki CGI czy też Fast CGI. Tego podejścia nie będę omawiał, ponieważ nie uważam tego za dobre podejście (m. in. przez duży narzut). Drugie podejście to postawienie własnego serwera HTTP. W ten sposób otrzymujemy jedną binarkę, którą wystarczy uruchomić. Oczywiście nadal możemy współpracować z Apachem, lighttpd czy nginxem ale o tym może kiedy indziej.

W Haskellu istnieją trzy większe frameworki do tworzenia takich rzeczy:
  • Happstack - najstarszy z nich, najbardziej rozbudowany ale jednocześnie niezbyt elegancki i szybki,
  • Yesod - mocno rozbudowany, najszybszy z dostępnych frameworków ale również niezbyt elegancki,
  • Snap - framework, który mi przypadł do gustu. Jest w miarę szybki, bardzo elegancki i niestety niezbyt rozbudowany.

Jako, że najbardziej lubię programować w Snapie to opiszę jak zbudować prostą stronkę w tym właśnie frameworku. Żeby ten kurs nie był znowu taki prymitywny to spróbujemy zbudować prostego CMSa. Zatem do dzieła!

1. Instalacja Snapa

Standardowo w Haskellu do instalacji wszelkich pakietów używa się programu o nazwie Cabal. Większość dystrybucji Linuxa posiada pakiet o nazwie cabal bądź cabal-install więc wystarczy go zainstalować. Co do wersji na windowsa to można ją ściągnąć stąd: http://www.haskell.org/cabal/download.html. Jak już go zainstalowaliśmy to wywołujemy:
$ cabal update
$ cabal install snap
To w zasadzie cała instalacja. W razie jakichkolwiek problemów napiszcie w komentarzach. Teraz spróbujmy coś uruchomić.

2. Hello world!

Utwórzmy sobie jakiś katalog na nasz projekt i przejdźmy do niego. Snap jest tak dobry, że utworzy nam w nim prostą i gotową do odpalenia stronkę. Wystarczy, że wywołamy: $ snap init default
Powinno nam się pojawić parę nowych katalogów oraz plik nazwa_katalogu.cabal W tym pliku znajdują się m. in. wszystkie nazwy pakietów, które wymaga nasza stronka, jakiś przykładowy opis strony i jej nazwa (taka jak nazwa katalogu) oraz nazwy plików źródłowych, które trzeba skompilować. No to kompilujemy:
$ cabal install
Gdy kompilacja się zakończy możemy uruchomić naszą stronkę:
$ dist/build/nazwa_katalogu/nazwa_katalogu
Powinniśmy otrzymać komunikat podobny do tego:
no port specified, defaulting to port 8000
User JSON datafile not found. Creating a new one.
Initializing app @ /
Initializing heist @ /
...loaded 7 templates from /home/karol/test/snaplets/heist/templates
Initializing CookieSession @ /sess
Initializing JsonFileAuthManager @ /auth

Listening on http://0.0.0.0:8000/
Snap informuje nas, że nie określiliśmy portu na jakim ma działać serwer więc będzie nasłuchiwał na porcie 8000. To odpalamy jakąś przeglądarkę i wpisujemy: http://localhost:8000


Snap ukazał nam domyślną stronę logowania, która oczywiście działa ale nie jest zbyt użyteczna, gdyż baza użytkowników znajduje się w pliku JSONa. Spróbujmy zatem coś z tym zrobić.

3. Pierwsze kroki

Czas na trochę kodu. Wyłączmy serwer poprzez naciśnięcie Ctrl+C i wyświetlmy plik src/Site.hs
W tym katalogu znajdują się jeszcze dwa inne pliki ale ich w ogóle nie będziemy ruszać więc na razie nie będę ich omawiał. W pliku Site.hs pierwszą rzeczą jaka nas interesuje to: To jest serce naszego systemu. Tutaj Snap decyduje co zrobić, gdy ktoś zażąda jakiegoś adresu. Proponuję wywalić pierwsze 3 wpisy i zamiast ich dodać pewien nowy w ten sposób: Informujemy w ten sposób Snapa, że gdy ktoś zażąda strony głównej to ma on wywołać funkcję o nazwie handleHelloWorld, która wyglądać będzie tak: Jeśli chodzi o typ funkcji to się tym na razie nie przejmujmy. Funkcja writeText to taki odpowiednik funkcji echo w PHP. Zanim zobaczymy efekt usuńmy wszystkie pliki z katalogu snaplets/heist/templates. Po czym wywołujemy jeszcze raz:
$ cabal install
i uruchamiamy:
$ dist/build/nazwa_katalogu/nazwa_katalogu
Teraz jak wejdziemy na http://localhost:8000 naszym oczom ukaże się przepiękne hello world!

Trudno byłoby programować dalej w ten sposób. Dlatego w kolejnej części kursu zajmiemy się systemem szablonów o nazwie Heist i pokażemy jak ułatwić sobie życie bez wiecznego przekompilowywania kodu. Tymczasem warto sobie poćwiczyć i dobrze opanować dzisiejszą lekcję. To do następnego razu!