ś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!

wtorek, 11 grudnia 2012

Mity edukacji

Czy lepiej jest pójść na studia czy raczej samemu próbować coś zdziałać? Tego typu pytania ostatnio coraz częściej pojawiają się na technicznych listach dyskusyjnych. Niestety rzadko kiedy ktoś daje jasną, zdecydowaną odpowiedź. Pomyślałem zatem, że może mnie się uda. Zanim jednak udzielę własnej opinii to przytoczę parę powtarzających się argumentów z obu stron:

Przeciwko studiowaniu:
  • na studiach uczysz się wszystkiego... niepotrzebnego,
  • sam uczysz się o wiele szybciej,
  • papiery i tak nie wiele dzisiaj znaczą,
  • studia kształcą tylko bezrobotnych.

Za studiowaniem:
  • 70% ludzi uczy się szybciej samemu ale prawie nikt nie wie czego powinien się uczyć,
  • studia nie są by przygotowywać ludzi do pracy ale by rozwijać "głód wiedzy",
  • duże firmy (korporacje) bez tytułu magistra a czasami nawet doktora nikogo nie zatrudniają.

Tak naprawdę to te argumenty są niewiele warte ale postaram się odnieść do każdego z nich. Zatem na pierwszy ogień idzie teza, że studia uczą samych nie potrzebnych rzeczy.

Studia jak każda inna firma czy też instytucja aby przetrwać musi realizować czyjeś potrzeby. A czyje potrzeby realizuje firma? No tych osób, które płacą. A kto zatem płaci? Nasuwa się od razu, że studenci co oczywiście jest bzdurą. Nawet w przypadku studiów prywatnych. Czesne na renomowanych amerykańskich uczelniach prywatnych pokrywają zaledwie 30% kosztów. W Polsce jest to jeszcze mniejszy procent. Amerykańskie uczelnie utrzymują się z dotacji prywatnych i państwowych, polskie natomiast praktycznie tylko z tych drugich. Czyje potrzeby realizują uczelnie? Rządu, ministerstwa czy też swoje własne "widzimisię" jeżeli dany rząd akurat daje im sporo swobody. Skoro studia nie realizują potrzeb studentów to chyba nie będzie przesadą stwierdzenie, że nie uczą one też w większości potrzebnych im rzeczy.

No dobrze ale skąd studenci mają wiedzieć czego właściwie potrzebują? Czy nie musimy im właśnie tego pokazać? Czy profesorowie tego nie wiedzą lepiej od nas samych? Z takiego myślenia wynika właśnie, że tak wiele osób pozostaje po studiach bez pracy. Dowiedzieć się naprawdę nie jest trudno. Po pierwsze musimy wiedzieć albo co chcemy robić albo ile chcemy zarabiać. Jak wiemy co chcemy robić to szukamy firmy lub też osoby, która to robi i dowiadujemy się co ona potrafi. Jeżeli wiemy ile chcemy zarabiać to szukamy zawodu, w którym osoby tyle zarabiają i tak samo dowiadujemy się od nich czego nam potrzeba. W dobie Internetu z takimi osobami możemy porozmawiać zupełnie za darmo i pewnie nam jeszcze pomogą się tego wszystkiego nauczyć. Wystarczy chcieć. Można też przejść się na rozmowę kwalifikacyjną ale nie po to by dostać pracę lecz po to tylko by zobaczyć test kompetencji i zorientować czego jeszcze nie potrafimy.

A może profesor też może nam takiej informacji udzielić? Warto kierować się w życiu zasadą, że zawsze uczymy się od ludzi, którzy osiągnęli już to co i my chcemy osiągnąć. Profesor może nam pomóc tylko w wypadku, gdy sami chcemy być profesorami :)

Głód wiedzy jest arcyciekawym argumentem. Najpierw trzeba by zdefiniować co to właściwie jest. Jak odczuwamy głód to oznacza mniej więcej tyle, że nie potrafimy myśleć o niczym innym jak tylko o tym jak zdobyć jedzenie. Zgodnie z tą przesłanką nie wydaje mi się żeby osoba głodna wiedzy czekała aż do studiów aby ktoś jej tą wiedzę podarował. Wydaje mi się raczej oczywiste, że taka osoba szuka wiedzy na wszystkie możliwe sposoby i nie zawraca sobie głowy tak długim procesem nauki jakim są właśnie studia. To raczej osoby, którym się nie chce idą do szkoły aby ktoś im wszystko pokazał żeby nie musieli sami szukać i się dowiadywać.

A co z papierami? Tu mogę pisać tylko z doświadczenia, a pracowałem u kilku pracodawców i znajomi pracowali, i znajomi znajomych, ba nawet sam byłem pracodawcą. Papier nie otwiera żadnych drzwi. Jedyne firmy, których to w ogóle obchodzi to firmy państwowe i korporacje. Tam faktycznie bez papierka nie wejdziemy. Jeżeli praca w korporacji jest naszym marzeniem to nie mamy niestety wyjścia (co do firm państwowych to mi by było wstyd pracować dla złodzieja). Oczywiście jak przejrzymy oferty pracy to prawie na każdym będzie widniało wymaganie aby być co najmniej studentem 5 roku. Jest to raczej efekt populizmu i nie należy się tym przejmować tylko wysyłać CV, a na pewno odpowiedzą i zaproszą na rozmowę.

To po co w ogóle istnieją uczelnie? Czy faktycznie tylko produkują bezrobotnych? Jak już pisałem wcześniej studia nie są ukierunkowane na studentów. Prawdę mówiąc to nigdy nie były. Studia to taki ośrodek badawczy dla profesorów, aby mogli prowadzić swoje badania czy to na potrzeby firmy czy też rządu. Im tylko na tym zależy, tylko na tym aby uzyskiwać granty i dotacje by móc prowadzić swoje badania. Nazwałbym je pieszczotliwie "ośrodkiem samorealizacji uczonych". I wcale nie chodzi o to aby ten profil zmieniać, a raczej chodzi o to aby to sobie uświadomić. Tylko my sami jesteśmy odpowiedzialni za to czego się nauczymy i czy będziemy mieli pracę. Ważne zatem jest by wiedzieć czym są uczelnie, a czym nie. A nie są na pewno miejscem, które zapewni nam pracę poza murem uczelni.

Wniosek z tego taki, że studiować się nie opłaca ale to nie oznacza wcale, że uczyć się nie opłaca. To właśnie zamiast studiować powinniśmy się uczyć i to o wiele więcej niż na studiach.

poniedziałek, 5 listopada 2012

Haskell Strings

Niedawno natrafiłem na stronę http://honza.ca/2012/10/haskell-strings, gdzie autor próbował napisać w Haskellu program realizujący takie oto proste zadanie:
  • Wczytaj plik o nazwie file, który zawiera jakieś zdania,
  • Zamień pierwszą literę każdego wyrazu na wielką,
  • Wypisz wynik na standardowe wyjście.

Ja utworzyłem sobie plik ważący 382 MB składający się z linii 'are you sure about this?'. Nie będę się długo nad tym rozwodził, wypiszę tylko najlepsze rozwiązanie jakie udało mu się znaleźć:



Czas: 0m46.615s

Autor przytacza rozwiązania w innych językach i niemal każde jest szybsze od tego w Haskellu. Weźmy na przykład jego rozwiązanie w C:



Czas: 0m4.027s

Postanowiłem spróbować pobić rozwiązanie autora w Haskellu. W rezultacie udało mi się stworzyć coś takiego:



Czas: 0m2.905s

Jak widać moje rozwiązanie okazało się szybsze od tego w C! Oczywiście rozwiązanie w C pewnie też można jeszcze poprawić ale to i tak nieźle. W każdym razie nie spodziewałem się takiego wyniku. Jeżeli do tej pory ktoś nie wierzył w szybkość programów napisanych w Haskellu to teraz chyba nie powinien mieć wątpliwości. Gorąco zachęcam do nauki!

środa, 27 czerwca 2012

Szydełkowo

Od dłuższego czasu niestety nic nie pisałem ale to wszystko z przyczyny, o której przeczytasz za moment. Otóż od ponad 2 miesięcy pracowałem nad własnym projektem sklepu internetowego w Haskellu. I... udało się! Oto jest szydełkowo! To moje pierwsze komercyjne i tak zawaansowane dzieło w Haskellu. Ale nie tylko ono jest pierwsze w moim życiu, również jest to moja pierwsza firma i moje pierwsze produkty. Znajdziesz tam sporo ręcznie wykonywanych rzeczy - rzeczy naprawdę robionych z pasji. Tak jak cały sklep w Haskellu. A przecież mogłem wykorzystać gotowe i darmowe rozwiązania. Tak, mogłem zrobić prościej ale pasja zwyciężyła. Niektórzy powiedzą, że wynajduję drugi raz koło, ale to nie prawda. Czy nie lepiej mieć 2 koła do wyboru i wybrać to lepsze? Ja właśnie chciałem być przede wszystkim lepszy, stworzyć coś co spodoba się ludziom dużo bardziej niż wszystko inne. Czy mi się udało? Sprawdź sam. Ja głęboko wierzę, że tak. A teraz parę słów o technikaliach:
  • wykorzystałem serwer http o nazwie Snap
  • wysyłanie e-maili odbywa się za pomocą HaskellNet
  • captcha generowana jest dzięki bibliotece hs-captcha
  • wykorzystałem nierelacyjną bazę danych
Jeżeli chodzi o możliwości sklepu to póki co zrobiłem to co uznałem za minimum, czyli:
  • dodawanie/edycja/usuwanie produktów
  • automatyczne tworzenie miniaturek
  • dodawanie/edycja/usuwanie newsów
  • obsługa zamówień
  • obsługa koszyka
  • generowanie wydruków z pomocą latexa
  • obsługa produktów indywidualnych - klient sam tworzy produkt na zasadzie prywatnej rozmowy poprzez sklep z jego obsługą i akceptacji wyceny. Taki produkt ląduje na jego osobistej liście produktów i w każdej chwili może go dodać sobie do koszyka.
Sklep i firmę mam zamiar dalej rozwijać i na pewno jeszcze nie jedno usłyszycie. Tymczasem zapraszam do zakupów!