Blog Macieja Ciemborowicza

Dlaczego nie programuję funkcjonalnie?

Wczoraj przeglądając devBlogi trafiłem na tłumaczenie artykułu Edwarda Garsona – „Stosuj zasady programowania funkcjonalnego”. Dziś jestem na 138-mej stronie książki „Python. Wprowadzenie” Marka Lutza i czytam o map oraz filter, „narzędziach programowania funkcjonalnego”.

Dlaczego ludzie nazywają „functional programming” „programowaniem funkcjonalnym”, a nie „programowaniem funkcyjnym”? Immortal, autor pierwszego tłumaczenia broni się:

Z tego co ja się orientuję termin „programowanie funkcjonalne” pochodzi od funkcjonałów, czyli funkcji wyższego rzędu (tj. takich które mogą zwracać i/lub przyjmować inne funkcje jako argumenty).

Jednak czy w takim wypadku nie należałoby przetłumaczyć tego zwrotu na „programowanie funkcjonału”? Spójrzmy na poniższy diagram, reprezentujący relacje między paradygmatami programowania:

The principal programming paradigms

Możemy zauważyć, że zarówno „functional programming” jak i „imperative programming” wywodzą się z „first-order functional programming”. „First-order function” to nic innego jak funkcja pierwszego rzędu. A „functional programming”, to nic innego jak programowanie pozwalające na korzystanie z funkcji zarówno pierwszego, jak i wyższych rzędów.

Jeśli jedno źródło to za mało, sięgnijmy dalej, do artykułu „Functional programming” w angielskiej Wikipedii. Słowo „functional” pojawia się tam wyłącznie w roli przymiotnika. W roli rzeczownika ani raz, w przeciwieństwie do licznych „function” oraz „functions”. Tak więc artykuł nie wspomina wprost o funkcjonałach, tylko co najwyżej funkcjach wyższego rzędu.

Kilka minut temu zastanawiałeś się, która forma jest poprawna? Mam nadzieję, że już nie masz wątpliwości. Programowanie funkcyjne, a nie programowanie funkcjonalne :).

Język programowania Scala

6-go kwietnia wygłaszałem w ramach seminarium licencjackiego EPI krótki referat dotyczący Scali. Jednym z warunków uzyskania zaliczenia jest opublikowanie tegoż referatu na uczelnianym serwerze. Pomyślałem sobie, że skoro już włożyłem w to tyle pracy (:P), to szkoda by było, gdyby się kurzył nigdy nie odnaleziony przez boty wyszukiwarek. Z tego powodu postanowiłem podlinkować go na blogu:

Zachęcam również do zapoznania się z oficjalną stroną Scali:

Oraz polską społecznością, która powoli, powoli się rozkręca:

object MyApp extends Application {
  println("Scala rządzi!")
}

Dwa równoległe serwery X Window

Po co?

Kiedy po raz pierwszy zetknąłem się z możliwością uruchomienia drugiego systemu operacyjnego w wirtualnej maszynie, od razu przyszedł mi do głowy pomysł, aby uruchomić go w odrębnym serwerze X. Dzięki temu mógłbym w bajecznie prosty sposób przełączać się między dwoma niezależnymi pulpitami za pomocą skrótów Ctrl+Alt+F7 oraz Ctrl+Alt+F8. Kolejnym powodem były problemy związane z uruchamianiem Wine w środowiskach graficznych z których ostatnio korzystam (Gnome oraz XFCE). Otóż po pierwsze – po przełączeniu się do innego okna poprzez Alt+Tab, nie mogłem z powrotem wrócić do okna z uruchomionym Counter-Strikiem. Po drugie, jeśli miałem włączony komunikator i ktoś do mnie napisał wiadomość, okno z grą stawało się nieaktywne i znów, musiałem uruchamiać ponownie Counter-Strika. Po trzecie, mam ustawione skróty klawiszowe, które włączają różne programy. Naciśnięcie ich w czasie gry było dość prawdopodobne (czytaj: zdarzyło mi się nie raz). Efekt taki jak wcześniej, brak dostępu do okna z grą. Uruchomienie Wine w odrębnym serwerze X eliminuje wszystkie te problemy.

Do dzieła!

Włączenie samych „X-ów” jest bardzo proste. Trzeba najpierw upewnić się, że nasz użytkownik jest do tego uprawniony. W pliku /etc/X11/Xwrapper.config powinien się znaleźć następujący wpis:

allow_user=anybody

Teraz uruchamiamy xinit:

xinit -- :1

Jeśli obecny serwer jest pod Ctrl+Alt+F7, to nowy znajdziemy pod Ctrl+Alt+F8. Tak uruchamiany Xorg skorzysta z domyślnego pliku .xinitrc. Nas interesuje włączanie różnych programów (czasem VirtualBoksa, czasem Wine), więc lepiej napisać odrębne skrypty dla każdego z nich. Ja postanowiłem umieścić je w katalogu ~/.xinit:

[ciembor@peace /]$ cd ~
[ciembor@peace ~]$ mkdir .xinit
[ciembor@peace ~]$ cd .xinit
[ciembor@peace .xinit]$ touch cstrike windows

~/.xinit/cstrike:

#!/bin/sh

######################
#  ~/.xinit/cstrike  #
######################

userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap
sysresources=/etc/X11/xinit/.Xresources
sysmodmap=/etc/X11/xinit/.Xmodmap

# merge in defaults and keymaps

if [ -f $sysresources ]; then
xrdb -merge $sysresources
fi

if [ -f $sysmodmap ]; then
xmodmap $sysmodmap
fi

if [ -f "$userresources" ]; then
xrdb -merge "$userresources"
fi

if [ -f "$usermodmap" ]; then
xmodmap "$usermodmap"
fi

# start some nice programs

wine ~/.wine/drive_c/Program\ Files/Valve/hl.exe -- hl.exe -game cstrike

~/.xinit/windows:

#!/bin/sh

######################
#  ~/.xinit/windows  #
######################

userresources=$HOME/.Xresources
usermodmap=$HOME/.Xmodmap
sysresources=/etc/X11/xinit/.Xresources
sysmodmap=/etc/X11/xinit/.Xmodmap

# merge in defaults and keymaps

if [ -f $sysresources ]; then
xrdb -merge $sysresources
fi

if [ -f $sysmodmap ]; then
xmodmap $sysmodmap
fi

if [ -f "$userresources" ]; then
xrdb -merge "$userresources"
fi

if [ -f "$usermodmap" ]; then
xmodmap "$usermodmap"
fi

# start some nice programs

twm &
VirtualBox

O ile przypadku Counter-Strika nie widziałem potrzeby uruchamiania menadżera okien, o tyle VirtualBoksowi by się przydał. Ja skorzystałem z TWM (bo na pewno go macie;)), jednak możecie skorzystać z czegoś bardziej estetycznego, np. FVWM albo Openboksa. Teraz możemy uruchomić skrypty:

xinit ~/.xinit/cstrike -- :1
xinit ~/.xinit/windows -- :2

Wpisywanie tego za każdym razem nie należy do rzeczy przyjemnych, więc sugeruję zrobić sobie aliasy w pliku ~/.bashrc.

alias cstrike='xinit ~/.xinit/cstrike -- :1'
alias windows='xinit ~/.xinit/windows -- :2'

Processing.js 1.0 – nareszcie!

Ukazała się wersja 1.0 JavaScriptowej implementacji frameworka Processing.

Processing przeznaczony jest do tworzenia wszelkiego rodzaju wizualizacji – od prostych grafik, po zaawansowane animacje fraktali. Na Wikipedii możecie przeczytać, że jest to język. Tak na prawdę Processing jest tylko rozszerzeniem środowiska Java, a konkretnie klasą PApplet.

W 2008 roku John Resig (twórca sławnej biblioteki JQuery) opublikował pierwszą wersję Processing.js, skryptu który tłumaczy w locie kod Processing na JavaScript i wyświetla grafikę korzystając z HTML5 zamiast z pluginu Javy. Po dwóch latach przepisywania kolejnych funkcjonalności i poprawiania błędów, w końcu ukazała się długo oczekiwana wersja 1.0. I dobrze się stało, ponieważ od września, kiedy to Microsoft wydał betę IE9, już wszystkie czołowe przeglądarki obsługują element <canvas>. Optymizmem napawają również intensywne prace nad WebGL i wydajnością JavaScriptu w Firefoksie 4. Rzecz jasna na popularyzację Processing.js trzeba będzie jeszcze trochę poczekać. Biorąc pod uwagę ciągłą obecność IE6 na rynku, to „trochę” można by nawet określić jako „dość długo”. Sukces projektu zależy też od tego jaki kierunek rozwoju Flasha obierze firma Adobe. Jestem jednak dobrej myśli i z niecierpliwością czekam na moment, w którym siadając przed uczelnianym komputerem nie będę musiał oglądać ostrzeżeń typu „No plugin is available to display this content”.

Tym, którzy chcieliby bliżej poznać Processing.js polecam przeglądnąć tutoriale i zagłębić się w dokumentację. Jeśli chcecie oglądnąć gotowe aplikacje, to http://www.processing.org/exhibition ciągle robi większe wrażenie niż http://processingjs.org/exhibition… ale to kwestia czasu;).

FPS Meter 0.1

Umieściłem wczoraj w addons.mozilla.org nowy dodatek. Wyświetla on w pasku stanu Firefoksa ilość wyświetlanych klatek na sekundę. Powstał na szybko, jako narzędzie do testowania wydajności mojego projektu z Animacji Komputerowej, jednak mimo paskudnego kodu i braku wodotrysków, jest w pełni funkcjonalny:). Przydałby się ktoś skory do przetestowania, bo nie wiem jak się to zachowuje pod innymi wersjami przeglądarki, ani pod innymi systemami operacyjnymi. Tak więc:

pobierajcie – FPS Meter 0.1 (download)
oceniajcie i komentujcie – FPS Meter 0.1 w addons.mozilla.org

Jeśli chodzi o przydatność dodatku, ma on zastosowanie wszędzie tam, gdzie przeglądarkę obciążają pętle zawierające złożony kod JavaScript. Najlepszym przykładem są animacje wykonywane z zastosowaniem elementu HTML5 – <canvas> oraz korzystających z niego bibliotek takich jak Processing.js.

TODO:

  • dodać opcję wyświetlania fps w oknie;
  • dodać monitor wyświetlający wykres zależności fps od czasu;
  • dodać zapisywanie ustawień użytkownika;
  • przenieść dodatek z „piaskownicy” do działu public.

GStreamer Editor 0.10.3.1 w AUR

W AUR pojawił się zauktualizowany PKGBUILD programu GStreamer Editor. Próba uruchomienia poprzedniej wersji kończyła się zwróceniem następującego błędu:

GStreamer Editor user interface file 'editor.glade2' not found.

Ponadto zmieniłem nazwę pakietu z gst-editor-0.10 na gst-editor. Zupełnie nie rozumiem, dlaczego nawet sam gstreamer w oficjalnym repozytorium ma na końcu to bzdurne „0.10″, przecież wersja jest oznaczona w polu tuż obok :|.

Zapraszam do testowania, wszelkie uwagi są mile widziane.

Dla niewtajemniczonych, GStreamer to framework wspomagający tworzenie programów przetwarzających dźwięk i obraz. Praca z nim przypomina trochę (a nawet bardzo) łączenie urządzeń kabelkami, tylko tutaj urządzenia są wirtualnymi pluginami, a kable zastępuje czysty potok danych:).

Writer’s Blog Theme – spolszczenie

Pozwoliłem sobie przetłumaczyć na język polski pewien (prawdopodobnie właśnie oglądany przez Ciebie) temat graficzny WordPressa. Od dzisiaj można go pobrać ze strony WordPress Polska. Jeśli jednak wolicie oryginał, znajdziecie go na WordPress.org.

System rozgłaszania wiadomości w oparciu o BotAPI

Ostatnio sporo rozmawiamy razem z kolegami w stałym gronie. Doszliśmy do wniosku, że warto by znaleźć jakiś rozsądny środek komunikacji, dzięki któremu każdy z nas byłby na bieżąco z informacjami. Oczywistym rozwiązaniem wydaje się konferencja Gadu-Gadu, jednak nie w każdym komunikatorze istnieje możliwość dodania jej jako odrębnego kontaktu. Tak więc na dłuższą metę nie jest to aż takie wygodne. Kolejną rzeczą która przychodzi na myśl, jest napisanie bota do EKG, który by rozgłaszał wiadomości do numerów zapisanch na liście, dodając w nagłówku nazwę nadawcy. Taki skrypt napisał niedawno mój kolega, jednak i z nim jest problem. Otóż Gadu-Gadu, w ramach walki ze spimem, ustawiło limity na ilość wysyłanych wiadomości, przez co część z nich jest filtrowana i nie dochodzi do wszystkich adresatów.

W końcu dotarłem do Platformy BotAPI. Możliwości są dość duże, boty są realizowane w postaci skryptów PHP, niemniej sam proces rejestracji może odstraszać. Jeśli po dwóch dniach wciąż nie otrzymaliście odpowiedzi na zgłoszenie, nie zniechęcajcie się, ja dostałem ją po około dwóch tygodniach :). Warto też zwrócić uwagę na limity, a szczególnie to jak się ich pozbyć:

Limity na wiadomości wysyłane przez skrypt mogą zostać zniesione w uzasadnionych przypadkach po podpisaniu porozumienia.

Porozumienia wciąż im nie wysłałem, ale bota już napisałem i działa całkiem nieźle. Nie jestem chamem, więc się podzielę :)

<?php

require_once 'GGBotApi/PushConnection.php';

/********************************/
/******* LISTA ROZMÓWCÓW ********/
/********************************/

$interlocutors = array(
  8112393 => array('Asia', 149, 179, 0),
  2876746 => array('Kasia', 179, 30, 0),
  3293012 => array('Zosia', 46, 116, 225),
  593815 => array('Basia', 179,119, 0)
);  // numer gg => (imię, r, g, b)
    // gdzie r, g i b to składowe koloru w jakim wyświetlane jest imię

/********************************/
/******* DANE POŁĄCZENIA ********/
/********************************/

$bot = array(
  'number' => 01234567,
  'login' => 'login@poczta.xy',
  'password' => '8jdk37fza8'
);

/********************************/
/********** BROADCAST ***********/
/********************************/

if (is_numeric($_GET['from']))  // jeżeli numer jest faktycznie numerem (przezorny zawsze bezpieczny)
{
  if (array_key_exists($_GET['from'], $interlocutors))  // jeżeli nadawca jest na liście
  {
    $message = new MessageBuilder('utf-8');
    $message->reply();  // jeśli tego nie będzie, bot wyśle do nadawcy pustą wiadomość (nielogiczne, ale... )

    $message->addText($interlocutors[$_GET['from']][0] . ':\r\n',   // imię
                      MessageBuilder::FORMAT_BOLD_TEXT, // pogrubienie
                      $interlocutors[$_GET['from']][1], // red
                      $interlocutors[$_GET['from']][2], // green
                      $interlocutors[$_GET['from']][3]  // blue
                    );  // dodaj do rozgłaszanej wiadomości nagłówek z imieniem nadawcy

    $message->addText(iconv('windows-1250', 'utf-8', $HTTP_RAW_POST_DATA)); // dodaj treść wiadomości wysłaną przez nadawcę

    unset($interlocutors[$_GET['from']]);  // usuwamy nadawcę z tablicy rozmówców, bo nie chcemy wysyłać do niego tego co sam napisał

    $message->setRecipients(array_keys($interlocutors)); // ustawiamy listę odbiorców wiadomości

    $BotAPIConnection = new PushConnection($bot['number'], $bot['login'], $bot['password']); // tworzymy nowe połączenie BotAPI
    $BotAPIConnection->push($message); // wysyłamy wcześniej utworzoną wiadomość
  }
}

?>

Skrypt jest bardzo prosty, starałem się go okomentować, ale zwróćcie uwagę na dwie linijki. Po pierwsze:

$message->reply();

Początkowo pominąłem wywoływanie tej metody. Było dla mnie oczywistym, że skoro nie chcę odpowiadać nadawcy, to nie powinem się nią interesować.  Przez długi czas głowiłem się nad tym, dlaczego za każdym razem kiedy nadawca coś napisze, dostaje pustą wiadomość od bota. Otóż właśnie dlatego, że nie wywołałem tej metody:).

Po drugie:

$message->addText(iconv('windows-1250', 'utf-8', $HTTP_RAW_POST_DATA));

$HTTP_RAW_POST_DATA (czyli wiadomość która przyszła do bota) jest zakodowana w windows-1250. Łańcuchy w PHP (na serwerze z którego korzystam) są kodowane w UTF-8. Z tego powodu rozgłaszana wiadomość była ucinana w miejscu wystąpienia pierwszego znaku diakrytycznego. Wywołanie funkcji iconv() rozwiązało problem.

Być może niedługo pokuszę się o dopisanie jakiejś linii komend… póki co nie mam dla niej sensownego zastosowania, ale byłby to fajny bajer :).

Tailgunner's News Core

Zeszłej nocy wraz z kolegami usilnie starałem się nie zamarznąć na ulicach Oslo. Łaziliśmy po mieście szukając miejsca w którym możnaby się ogrzać. Jednym z takich miejsc okazał się pub o nazwie Evergreen przy ulicy Pilestredet 39. Nie będę się uęalał nad wysokimi cenami trunków, przejdźmy do rzeczy. W pubie tym zagadał do nas pewien słabo kontaktujący Norweg (aka Jani). Gdy dowiedział się, że jesteśmy z Polski, podekscytowany zaczął czegoś szukać. Co się okazało – jego przyjaciel (aka Tailgunner) nagrał płytę. Nie byłoby w tym nic nadzwyczajnego, gdyby nie fakt, że jest ona oparta wyłącznie o sample polskich muzyków. Pozwolę sobie wymienić: Czesław Niemen, Michał Urbaniak, SBB, Marek Grechuta, Breakout, Wojciech Karolak, Adam Makowicz, Czesław Bartkowski, Urszula Dudziak, Katowice Big Band, Piotr Figiel, Novi Singers, Zbigniew Namysłowski, Czerwone Gitary, Bemibem, Ossian i wielu innych. Mieszanka wybuchowa:).

Pierwsze dwa kawałki nie przypadły mi do gustu, trochę raziły rojeżdżające się w czasie ścieżki. Jednak piąty numer, „Sans Papier”, bardzo mi się spodobał. Zaraz po nim równie ciekawy „One for Alex [becouse he was shot]„. Mimo, że nagraniu sporo brakuje do twórczości mistrzów takich jak Amon Tobin czy Bonobo, jest ono warte uwagi, chociażby ze względu na ciekawą, polską genezę. Aż dziw, że u nas nie robi się takich rzeczy (pomijam Skalpel).

Taigunner's News Core

Muzyczny kolaż w AUR

Dzięki inicjatywie społeczności ArchAudio, Arch Linux coraz lepiej radzi sobie z przetwarzaniem dźwięku. Niestety, ciągle brakuje ludzi aktualizującycych skrypty instalacyjne w AUR. Co za tym idzie, często nie są one kompatybilne z nowymi wersjami kompilatorów. Postanowiwszy poświęcić temu problemowi trochę czasu, dodałem dziś dwa programy zwane z angielskiego beat slicerami. Służą one do cięcia ścieżek audio na sample, które później z powodzeniem mogą być wykorzystane jako składniki loopów.

Gorąco zachęcam do testowania i zgłaszania ewentualnych uwag.

 

Nawigacja