čtvrtek, 30. prosince 2010

Nekonečné datové struktury a Microsoft LINQ

Nekonečné datové struktury jsou zajímavá věc ze světa funkcionálních programovacích jazyků, dají se vytvořit i v C# s použitím knihovny Microsoft LINQ.
Na první pohled to zní jako nesmysl, protože paměť počítače je konečná a tak se do ní nekonečná datová struktura přece nemůže vejít.
To je samozřejmě pravda, ale funkcionální programování (ze kterého LINQ vychází) zná pojem "lazy evaluation", který práci s nekonečnými strukturami umožňuje. Podívejme se na následující příklad:


using System;
using System.Collections.Generic;
using System.Linq;

// Hledání prvočísel - Erasthotenovo síto pro C# 3.0 a LINQ
// založeno na učebním algoritmu Erasthotenova síta v jazyce Haskell
// (c) Jan Stoklasa 2008

static class SieveOfErasthotenes
{
static void Main()
{
foreach (var i in primes().Take(100)) //vytiskne prvních 100 prvočísel
{
Console.WriteLine(i);
}
}

public static IEnumerable<int> primes()
{
return sieve(integersFrom(2));
}

//"Nekonečná" datová struktura
//Nekonečný cyklus generuje všechna přirozená čísla od start včetně
public static IEnumerable<int> integersFrom(int start)
{
for (int i = start; true; i++) 
{
yield return i;
}
}

//Erasthotenovo síto 
//První prvek seznamu xs je prvočíslo. Přidáme ho do výsledku,
//přeskočíme ho a v seznamu necháme pouze čísla která nejsou dělitelná 
//prvním prvočíslem
public static IEnumerable<int> sieve(IEnumerable<int> xs)
{
int prime=xs.First();
yield return prime;
foreach(var i in sieve(xs.Skip(1).Where( a => a % prime > 0))) 
{
yield return i;
}
}
}



Program funguje tak že metoda integersFrom vrací "nekonečný" seznam všech celých čísel od zadaného parametru a metoda sieve filtruje tento seznam a nechává v něm pouze "všechna" prvočísla.

V metodě integersFrom je nekonečný cyklus for (int i = start; true; i++) a to vypadá hodně podezřele. Testovací podmínka tohoto for cyklu je vždycky true a tak se zdá že budeme pořád zvětšovat i o jedničku, a pořád, a pořád, a nikdy neskončíme.
Zkusme to - pokud ale program spustíme, řádně doběhne a vytiskne prvních 100 prvočísel. To je zvláštní,  vždyť program který se dostane do nekonečného cyklu přece nikdy normálně neskončí! To se každý učil v základním kurzu programování a každý si jednou napsal program který donekonečna vypisuje "Hello World".

Jak je to možné? Ve světě C# 3.0, LINQ a funkcionálního programování nejsou "nekonečné cykly" tak úplně nekonečné. Klíčové slovo yield totiž přerušuje vykonávání cyklu a výpočet pokračuje dál na jiném místě kódu. Do "nekonečného" cyklu se výpočet vrátí později, až bude metoda sieve potřebovat další přirozená čísla. "Nekonečný" seznam všech přirozených čísel se tedy negeneruje najednou, to by se ostatně nevešel do konečné paměti počítače, ale po částech podle potřeby, tak jak běží výpočet. V tom je hlavní myšlenka tohoto příkladu a také podstata myšlenky "lazy evaluation". "Lazy evaluation" pochází ze světa funkcionálního programování a hodně jí využívá zajímavý programovací jazyk Haskell.

K čemu je to dobré? Představte si že v reálném čase analyzujete ceny akcií na burze, váš algoritmus pracuje s posloupností cen akcií a nějakým způsobem hledá maxima, minima a tendence změn v několika po sobě jdoucích hodnotách. Pokud nepoužijte "lazy evaluation", budete muset v některé fázi vašeho programu průběžně načítat další hodnoty z posloupnosti, takže kód který provádí analýzu cen bude promíchán s kódem který načítá další data. Pokud použijete "lazy evaluation", můžete s posloupností cen pracovat jako by byla nekonečná a probíhající výpočet si v pravou chvíli natáhne další prvky posloupnosti.

Programovací jazyk F#





Pokud Vás zajímá C# a Microsoft LINQ, určitě si vyzkoušejte programovací jazyk F#. F# je zajímavý programovací jazyk od Microsoftu který patří do rodiny funkcionálních jazyků. Autoři jazyka F# pracovali i na návrhu technologie LINQ takže pokud Vás LINQ zajímá do hloubky může pro Vás být zajímavé seznámit se s původním zdrojem idejí které vedly k návrhu této technologie.
Funkcionální programování přichází z akademického světa ale Microsoft podporuje F# na stejné úrovni jako svoje "hlavní" programovací jazyky C# a Visual Basic. V F# tedy máte k dispozici všechny třídy a knihovny prostředí Microsoft .NET které používají programátoři v C# a Visual Basicu. V F# můžete programovat weby a firemní aplikace protože k dispozici budete mít veškeré objekty které k tomu můžete potřebovat - knihovny GUI, ASP.NET pro tvorbu webových stránek, databázové knihovny, knihovny pro XML... Jazyk F# přímo podporuje i vývojové prostředí Visual Studio .NET.
Některé funkcionální jazyky používají dynamické typování ale F# je silně typovaný programovací jazyk který má navíc hezkou vlastnost automatického odvození typů - takzvanou typovou inferenci. V F# nemusíte deklarovat typy každé proměnné a funkce tak jak je to obvyklé v C#, C++ a Javě, překladač si ve většině případů dokáže typy inteligentně "domyslet".
Největším českým odborníkem na F# je pan Tomáš Petříček. Na jeho stránkách http://tomasp.net najdete pěkný úvod do jazyka F#:
F# Overview (I.) - Introduction
F# Overview (II.) - Functional Programming
F# Overview (III.) - Imperative and Object-Oriented Programming
F# Overview (IV.) - Language Oriented Programming
a ukázky z jeho nové knihy Functional Programming for the Real World: With Examples in F# and C#.

středa, 27. října 2010

Komiksová kniha Land of Lisp právě vyšla

Po dvou letech autor dokončil komiksovou knihu Land of Lisp a na http://landoflisp.com je roztomile dětinské propagační video. Už se tu knihu snažím koupit...

pondělí, 21. června 2010

Prezentace z dnešního semináře CTU Open

Prezentace z dnešního semináře k přípravě na CTU Open ke stažení: http://f.lisp.cz/PripravaNaCtuOpen2010.pdf

pondělí, 7. června 2010

Příjemný online tutorial jazyka Haskell

Hezký interaktivní tutorial funkcionálního programovacího jazyka Haskell je na http://tryhaskell.org. Tento web je inspirován podobným tutoriálem pro jazyk Ruby, bez lokální instalace máte k dispozici příkazovou řádku jazyka ve které si můžete vyzkoušet základní příkazy jazyka a nejdůležitější konstrukce jazyka včetně (jsme ve funkcionálním jazyce) práce se seznamy.

sobota, 15. května 2010

Closures v Javě - budou nebo nebudou?

Docela mě zajímá jestli v Javě nakonec budou anonymní lambda funkce neboli closures, konečně by Java byla víc jako Lisp :-) Odpovědi na toto téma se různí, chvíli se domnívám že ano a pak zase že ne, David Flanagan na svém blogů říká že ne: http://www.davidflanagan.com/2010/05/closures-in-jav.html
Vážení čtenáři, nevíte o tom něco víc? Pište do komentářů...

středa, 12. května 2010

Land of Lisp - komiksová kniha o Lispu

Conrad Barski je autorem komiksového tutorial Lispu který už jsem na blogu zmiňoval: http://www.lisperati.com/casting.html. Teď pracuje na komiksové knize o Lispu a musím říct že si jí asi koupím: http://nostarch.com/lisp.htm.
Jeho programátorské komiksy jsou vtipné ale současně se z nich člověk hodně věcí naučí, má to svoje kouzlo...

Zelená obludka na obalu knihy je jakýmsi neformálním maskotem Lispu - na první pohled vypadá podivně ale na druhý pohled si jí oblíbíte... stejně jako Lisp :-)

pátek, 23. dubna 2010

Hry v Lispu

Lisp bývá považován za akademickou záležitost ve které seriózní výzkumníci programují umělou inteligenci, navigační systémy družic a další vážné záležitosti. Komunita kolem Lispu se ale umí i bavit - podívejte se na hry a hříčky které naprogramovali účastníci soutěže 2010 Lisp Game Design Challenge: http://dto.github.com/notebook/lgdc.html

středa, 7. dubna 2010

Haskell REPL jako webová služba

Haskell je pěkný funkcionální programovací jazyk který mám stejně tak rád jako Lisp ;-). Fanoušek Haskellu Chris Done zprovoznil webovou službu na které si můžete Haskell vyzkoušet bez toho abyste instalovali interpret a kompilátor: http://chrisdone.com/posts/2010-04-05-haskell-json-service-tryhaskell.html
Služba se dá používat přes webový formulář nebo přes JSON. Líbí si mi funkce load která je stavová a na webu funguje stejně jako nahrání souboru v interpretu. Díky ní můžete v jednom volání definovat proměnné a funkce které v dalších voláních použijete.

pondělí, 22. března 2010

Co se od Lispu mohou naučit ostatní programovací jazyky

Velmi dlouhý ale zajímavý článek o tom jak se některé ideje Lispu projevují v jiných programovacích jazycích a v jazyce XML:
http://www.defmacro.org/ramblings/lisp.html

neděle, 14. března 2010

Inteligentní agenti hrají populárního "Mária"

Zábavnou aplikací inteligentních agentů je Mario AI Championship.
Soutěžící implementují inteligentní agenty kteří hrají klasickou hru Super Mario a výsledky vypadají opravdu zábavně. Agentovu přesnost v proskakování mraku obludek můžete vidět na http://www.youtube.com/watch?v=DlkMs4ZHHr8.

pondělí, 1. března 2010

Implementace Lispu z pradějin IT

zdroj: http://www.frobenius.com/univac.htm

Lisp je žijící klasik computer science a IT. Přesvědčit se o tom můžete v zajímavém článku o implementaci Lispu z poloviny šedesátých let. Tato implementace běžela na (tehdy) komerčně úspěšných sálových počítačích Univac a kompletní interpret a překladač měl 5000 řádků v assembleru a 1000 řádků v Lispu. Docela úsporné programování, co říkáte?


P.S. Se slečnou programátorkou bych si dal rande ale nevím jestli je to ještě aktuální :-)

úterý, 23. února 2010

Úlohy ze světového finále soutěže ACM ICPC

Úlohy z letošního světového finále soutěže ACM ICPC byly na webu trochu schované, můžete si je stáhnout na https://cm.baylor.edu/ICPCWiki/attach/Problem%20Resources/2010WorldFinalProblemSet.pdf. Podívejte se čím se ve zmrzlém Harbinu bavili reprezentanti nejlepších světových univerzit a třeba si některé z těch úloh pro radost vyřešte.
Každá z úloh by v některých vysokoškolských předmětech byla kvalitním zadáním semestrálky, nejlepší týmy těchto úloh vyřešili během pět hodin sedm. Myslím že takovým studentům bych dal bez váhání jedničku :-)

středa, 10. února 2010

Momentky z Číny a programátorská soutěž ACM ICPC

Čínská cesta se mi moc líbila, světové finále programátorské soutěže ACM ICPC bylo jako vždy vynikající a čínskou exotiku jsem si opravdu užíval.

Začnu tím důležitým, programátorská soutěž ACM ICPC je vlastně neoficiálním mistrovstvím světa v programování. Tříčlenné týmy řeší úlohy algoritmického charakteru a musejí je v omezeném čase nejen vyřešit ale i správně implementovat. Pokud se chcete porovnat s nejlepšími, zkuste si úlohy z loňského finále na http://cm.baylor.edu/resources/pdf/2009Problems.pdf (letošní úlohy ještě nejsou na webu). Vítězi světového kola se stali čínští studenti z Shanghai Jiaotong University, druhá byla Moskevská univerzita a třetí National Taiwan University, nejlepší z našeho regionu byla Varšavská univerzita na osmém místě - kompletní výsledky jsou na http://cm.baylor.edu/ICPCWiki/Wiki.jsp?page=Results%20World%20Finals%202010.

Soutěživé povahy mezi Vámi zvu do soutěže CTU Open která proběhne u nás na ČVUT na podzim. Náš tým pod vedením kolegyně Mannové a kolegy Kubra pořádá CTU Open jako kvalifikaci pro soutěž ACM ICPC - sledujte soutěžní web na http://contest.felk.cvut.cz/.

Co se týká mých dojmů z Číny, jsou opravdu bohaté a silné a myslím že obrázky budou lepší než pokus o cestopis. Tady jsou fotky, kolegovi Kubrovi děkuji za poskytnutí fotografií (klikněte pro větší verzi):

Za chvíli si k těmhle stolkům sednou nejlepší světové týmy programátorů

Za každou vyřešenou úlohu dostane tým barevný balónek - to je hezká tradice

Soutěž se konala ve městě Harbin na severu Číny. V Harbinu je zima a nejdelší promenáda v Asii.

Sněhové skulptury jsou turistickou atrakcí Harbinu

... a kromě sněhu je v Harbinu i led :-) a ledové město

Jídlo bylo skvělé a porce ohromné - tohle je čínská obdoba českého jelita se zelím. Dobrou chuť!

pondělí, 18. ledna 2010

Blogovací prázdniny

Zdravím všechny čtenáře tohoto "blogísku".
Mířím teď na delší služební cestu takže dalších dva týdny bude blog nejspíš spát, ale v únoru budeme zase s radostí pokračovat.

pátek, 15. ledna 2010

Implementace datové struktury typu seznam s použitím lambda funkcí

V semestrální práci kolegyně Fedorové mě zaujala implementace datové struktury typu fronta s použitím lambda funkcí. To je hezká myšlenka funkcionálního programování kterou teď zkusím ilustrovat na jednodušším příkladě.

Otázka: Kdyby v Lispu nebyly operace cons, car a cdr, mohl bych si je nějak implementovat sám?
Odpověď: Ano (vzpomínám si že napoprvé mě taková odpověď celkem překvapila).

Definujme trojici funkcí vyššího řádu cons-lambda, car-lambda, cdr-lambda:

 (defun cons-lambda(x y)
  (lambda(f)
    (funcall f x y)))

(defun car-lambda(pair)
  (funcall pair (lambda(x y) x)))

(defun cdr-lambda(pair)
  (funcall pair (lambda(x y) y)))


Cons-lambda, car-lambda a cdr-lambda se pak chovají stejně jako cons, car a cdr:

(setf pair (cons-lambda 2 3))
(car-lambda pair)   ; => 2
(cdr-lambda pair)   ; => 3

(setf list (cons-lambda 1 (cons-lambda 2 (cons-lambda 3 nil))))
(car-lambda list)                                              ; => 1
(car-lambda (cdr-lambda list))                        ; => 2
(car-lambda (cdr-lambda (cdr-lambda list)))  ; => 3
(cdr-lambda (cdr-lambda (cdr-lambda list)))  ; => NIL

Jak by řekl můj bombajský kolega Raj, "it's cool man!" :-)

Tenhle příklad je jen malou ukázkou možností lambda funkcí a lambda kalkulu. Mezi výzkumníky v oboru funkcionálního programování je populární série článků "Lambda: The Ultimate...." ve které se s pomocí lambda funkcí modelují různé rysy programovacích jazyků (Lambda: The Ultimate Imperative, Lambda: The Ultimate Declarative).

Vztah mezi funkcionálním programováním a návrhovými vzory



Internetové demotivátory jsou vtipné a občas se v nich vyskytuje zrnko pravdy. Demotivátor na téma vztahu mezi funkcionálním programováním a návrhovými vzory mě zaujal - něco na tom je...

středa, 13. ledna 2010

Jak vidí uživatelé programovacího jazyka jiné jazyky (pěkný internetový mem)


(programovací jazyky z pohledu fanoušků jiných jazyků - klikněte pro větší verzi.
Zdroj: http://hallakol.tumblr.com)

Co se mého názoru týká, nepochybuju o tom že Matrix je naprogramovaný v Lispu :-) Jsem i fanouškem programovacího jazyka Haskell ale moje názory na další jazyky nejsou tak vyhraněné jako na obrázku - ale chápu že legrace musí být!

pondělí, 11. ledna 2010

Integrál funkce v Lispu

V článku http://www.lisp.cz/2010/01/derivace-funkce-v-lispu.html je popsána numerická derivace funkce v Lispu. Na konci článku jsem slíbil že se podíváme i na integrál funkce:

Definujte funkci integral která má na vstupu funkci a vrací funkci která je jejím integrálem. Integrál počítejte numericky pomocí lichoběžníkové metody (http://en.wikipedia.org/wiki/Trapezoidal_rule) .  
(že by námět do dalších písemek? ;-)

Podobně jako jsme v http://www.lisp.cz/2010/01/derivace-funkce-v-lispu.html definovali derivaci

(defun derivace(f)
  (lambda(x)
    (/ (- (funcall f (+ x epsilon))
          (funcall f x))
       epsilon)))


můžeme definovat funkci integral která vrací anonymní lambda funkci která je numerickým integrálem funkce f:

(defun integral(f)
  (lambda(x)
    (let* ((interval 1/10000)
              (n (/ x interval))
           (sum 0.0))
      (dotimes (k (- n 1))
        (incf sum (funcall f (* (+ k 1) interval))))
      (* (/ x (* 2 n))
         (+ (funcall f 0) (* 2 sum) (funcall f x))))))


Tato funkce je přesným přepisem vzorce

z http://en.wikipedia.org/wiki/Trapezoidal_rule s tím že a=0,b=x, sum je součtem členů od f(x 1) do f(x n-1) který pak vynásobím dvěma a přičtu k němu f(x0) a f(xn).

A teď si budeme hrát:
(funcall (integral (lambda(x) 7)) 2)  ; => 14
(funcall (integral (lambda(x) 7)) 3) 
; => 21
Integrál konstatní funkce k je kx, 2*7 je 14 a 3*7 je 21.
(funcall (integral (lambda(x) (* 3 x x))) 2)  ; => 8.000005
Integrál(3x^2)=x^3 a 2^3 je skutečně 8.
Taky by mělo platit že integrál derivace f je f a derivace integrálu f je zase f:
(funcall (integral (derivace (lambda(x) (* 5 x)))) 3)   ; => 15, což je 5*3
(funcall (derivace (integral (lambda(x) (* 5 x)))) 3)   ; => 60001/4000, což je 15.00025

Až na numerické nepřesnosti to sedí... Ten Lisp je nějaký chytrý, asi na hodinách matematiky dával pozor :-)

A co taková exponciální funkce se základem e (2.7182818)?
(funcall (integral #'exp) 1) => 1.7182825
(funcall (integral #'exp) 2) => 6.38906
O exponenciální funkci z hodin matematiky víme že integrál(e^x) od a do b = e^b-e^a, v našem případě a=0, b=1 nebo 2:
(- (exp 1)  (exp 0)) => 1.7182818
(- (exp 2)  (exp 0))
=> 6.389056
Až na numerické nepřesnosti je to ok.

Tak jako je e^x je svojí vlastní derivací

(funcall (derivace #'exp) 1) => 2.720356
(exp 1)
=> 2.7182818, až na numerickou nepřesnost to sedí
(funcall (derivace #'exp) 2) => 7.3862076
(exp 2)
=> 7.389056, až na numerickou nepřesnost to sedí

tak je "skoro" i svým vlastním integrálem, až na jedničku (exp 0).
To mi připomíná populární matfyzácký vtip:
Jde po mostě skupina funkcí a vesele si prozpěvuje. Potká je stará, hnusná, svraštělá derivace a křikne: "Pojďte sem, já vás všechny zderivuju!" Funkce se leknou a naskáčou z mostu do řeky. Jen jedna jde dál a vesele si prozpěvuje: "Já jsem e na x-tou, já jsem e na x-tou..." A stará svraštělá derivace se zachechtá a zderivuje ji podle y.

No není ta matematika zábavná?

čtvrtek, 7. ledna 2010

Derivace funkce v Lispu


(tahle písemka taky stojí za to - klikněte pro větší verzi. Zdroj: collegehumor.com

V opravné písemce byl zajímavý a z hlediska funkcionálního programování důležitý příklad na který se teď podíváme podrobněji. Zadání znělo:
Definujte funkci derivace která má na vstupu funkci a vrací funkci která je její derivací. Derivaci počítejte přibližně numericky pomocí Newtonova vzorce f’(x)= (f(x+epsilon)-f(x)) / epsilon , kde epsilon je velmi malá hodnota blízká nule.

Řešením je funkce která má jako parametr funkci a vrací jinou lambda funkci (neboli funkce vyššího řádu neboli higher order function):

středa, 6. ledna 2010

Písemky jsou náročné


(tahle písemka stojí za to - klikněte pro větší verzi)

... i pro učitele.... :-(
Těšil jsem se že zatímco v semestru se učitelé připravují a studenti paří, tak že ve zkouškovém se situace obrátí. Ale zatím to tak nevypadá, připravuju se na zítřejší opravnou písemku z Lispu. Vymýšlím a ladím nějaké pěkné hádanky, takže zítra to pořádně rozjedem!

Programovací jazyk Haskell


(Zdroj: http://www.haskell.org - logo programovacího jazyka Haskell)

Programovací jazyk Haskell je staticky typovaný funkcionální programovací jazyk se silným typovým systémem. Osobně ho považuji za jeden z nejzajímavějších programovacích jazyků vůbec, akademičtí výzkumníci kteří se zabývají Haskellem patří mezi špičku a nápady které vymýšlejí v Haskellu se občas objevují v mainstreamových programovacích jazycích.
Pokud vás funkcionální programování a jazyk Lisp zaujaly, podívejte se i na Haskell.
Zajímavými rysy Haskellu je statické typování s generickými typy a typovou inferencí (type inference) a líné vyhodnocování (lazy evaluation).
Statické typování v Haskellu funguje podobně v populárních staticky typovaných jazycích jako je Java, C++ a C# - každá proměnná a funkce má přesně daný typ který je známý v době překladu - tím se liší od dynamicky typovaných jazyků jako je Lisp, Smalltalk nebo i třeba PHP. 
Generické typy jsou obdobou generik z Javy a C# nebo šablon C++ (Zajímavé je že generické typy byly do Javy přidány na základě prací funkcionálních výzkumníků - pánové Martin Odersky a Philip Wadler). 
Typová inference je schopnost kompilátoru odvozovat typy proměnných a funkcí automaticky bez toho aby se musely pokaždé deklarovat (zmiňoval jsem se o ní už u jazyků OCaml a F#).
Líné vyhodnocování je práce s "nekonečnými" datovými strukturami. Nekonečné struktury se samozřejmě nevejdou do konečné paměti počítače, ve skutečnosti se jedná o potenciálně nekonečné struktury které si program za běhu dopočítává podle potřeby.

pondělí, 21. prosince 2009

Funkcionální programování na Wall Street

Funkcionální programování je velmi vhodné pro řešení problémů matematického charakteru. V moderním finančním světě se pro obchodování na burze používají silné matematické modely a to je pro funkcionální programování přirozená aplikační oblast.
Společnost Jane Street Capital používá pro svůj interní vývoj funkcionální programovací jazyk OCaml (pdf): http://www.janestreetcapital.com/minsky_weeks-jfp_18.pdf

středa, 16. prosince 2009

Studijní materiály k programovacímu jazyku Prolog


(Zdroj: http://www.atarimagazines.com/startv2n5/prolog.html - historický článek o Prologu na počítači Atari ST v roce 1988)

Prolog je založen na takzvaném programování v logice a má silné teoretické základy v matematické logice. Tím se ale nenechte odradit,  s Prologem se dá dobře hrát i bez znalosti matematické logiky.
Prolog se někdy označuje jako logický programovací jazyk a říká se o něm že je deklarativní. To znamená že na rozdíl od imperativních programovacích jazyků kde popisujete JAK se má spočítat výsledek popisujete CO chcete spočítat a Prolog to "spočítá sám od sebe".
Prolog je tajemný a zajímavý jazyk, skoro bych řekl že je ještě tajemnější než Lisp a to je co říct!
Naštěstí jsou k němu pěkné studijní materiály, takže věřím že jeho zvládnutí bude pro Vás hračkou:
Krásná skripta pana Koláře o funkcionálním programování a Lispu a o programování v logice a Prologu jsou na
http://service.felk.cvut.cz/courses/36JUI/jui.zip, Prolog je od strany 177 respektive 180 dál (Poznámka: tento odkaz je dostupný pouze pro čtenáře se školním účtem)
Další pěkná skripta napsal profesor Kryl z matfyzu a jsou dostupná na http://ksvi.mff.cuni.cz/~kryl/prolog.pdf . Vzpomněl jsem si na studentská léta kdy jsem se právě z těchto skript učil Prolog na zkoušku a bylo to fajn ;-)

pondělí, 14. prosince 2009

Hraní s inteligentními agenty, aneb jak na semestrálku


(Zdroj: http://www.lispers.org) 
Jak jsem slíbil, tady je malý návod jak začít s hraním s inteligentními agenty a se semestrálkou (a už jsem si vzpomněl co znamená chyba "Incomplete s-expression in region", viz bod 5).
1. Z http://service.felk.cvut.cz/courses/36JUI/ si stáhněte a rozbalte "Balíček potřebných souborů - NOVÁ VERZE" (http://service.felk.cvut.cz/courses/36JUI/ProjectFiles.zip)
(Poznámka pro mimoškolní čtenáře: potřebné soubory se dají najít v repozitáři na http://aima.cs.berkeley.edu/lisp/doc/overview.html)

sobota, 5. prosince 2009

Příklad ze cvičení - lambda transformace kódu

Přepište výraz (let ((x 10) (y 20)) (+ x y) (list x y)) bez použití let. (Nápověda: pomocí nepojmenovaných funkcí – lambda výrazů)

Tenhle příklad jsem na cvičení moc nevysvětlil ale přitom je zajímavý, podíváme se na něj. Výsledek výrazu je možné napsat rovnou jako '(10 20) ale o to nám v úloze nejde. Pointou je následující úprava kódu:
((lambda(x y) (+ x y) (list x y)) 10 20)

pátek, 27. listopadu 2009

Jedna minimalistická

(cdr '(jaka-je-nejdelsi-reka-Afriky?))

středa, 25. listopadu 2009

Horečnaté přípravy na písemku z Lispu


(obrázek z wikipedia.com)

Tak, rtuť teploměru pěkně šplhá nahoru a já dolaďuju příklady na zítřejší písemku.
Volně podle Cimrmanů, písemka, ta se holt nezakecá a vždycky přijde :-(
Myslím že to bude dobrý, ty příkládky by mě jako řešitele celkem bavily.

čtvrtek, 19. listopadu 2009

Naprogramujte si v Lispu "malý Google"

Na cvičení jsem se zmiňoval o Google MapReduce. MapReduce je v podstatě funkcionální princip distribuovaných výpočtů který Google používá pro rozložení zátěže mezi svoje servery (těch serverů jsou odhadem desetitisíce). MapReduce je podrobně popsaný v článku na http://labs.google.com/papers/mapreduce.html .

Zkusíme si na tomto principu naprogramovat zjednodušenou ukázku. Název MapReduce odkazuje na dvě funkce vyššího řádu známé z funkcionálního programování: map (v Lispu známé pod názvem mapcar) a reduce
(v jiných funkcionálních jazycích známé pod názvem fold) a princip MapReduce využívá jejich kombinaci.

čtvrtek, 12. listopadu 2009

Funkce Reduce neboli Fold - tajemná zbraň funkcionálního programování

Na cvičení jsme se setkali s hezkým až tajemným příkladem využití lispovské funkce reduce a tak se na ní teď podíváme.
Funkce reduce patří do výzbroje každého funkcionálního programátora. Je to funkce vyššího řádu (higher-order function) protože jejím prvním parametrem je funkce dvou parametrů a dalším parametrem je seznam . 

středa, 4. listopadu 2009

Google Wave



Jeden malý offtopic, hrál jsem si s Google Wave a vypadá to zajímavě, zjednodušeně řečeno je to kombinace mailu a chatu. Jestli se chcete na Google Wave podívat ještě dřív než bude k dispozici ostrá verze, mám ještě k dispozici nějaké pozvánky do testovací verze. Napište mi na jan.stoklasa at gmail.com a já vás rád zařadím do svého seznamu pozvánek.

pondělí, 2. listopadu 2009

Proč se v příkladech kódu používají názvy foo a bar?

V příkladech kódu můžete často vidět "podivné" názvy foo a bar a jeden kolega se mě zeptal proč se používají právě takovéto názvy když zdánlivě nedávají žádný smysl.
Názvy foo a bar jsou stará programátorská tradice která má svoje kořeny v armádním slangu a používají se pro názvy funkcí a proměnných tam kde na názvu nezáleží. 
Hezký popis této tradice najdete v kultovním "hackerském slovníku" (Hacker's Dictionary) u hesla "foo": http://www.hackersdictionary.com/html/entry/foo.html. Hacker's Dictionary obsahuje i spoustu jiných zajímavých hesel a je to pěkné čtení pro všechny zájemce o počítačovou historii a počítačový folklór.
A ještě jedna perlička na závěr, název kapely Foo Fighters je ze stejného zdroje jako naše počítačové "foo" :-).

sobota, 31. října 2009

Programovací jazyk F# - funkcionální programovací jazyk pro Microsoft .NET



Pokud programujete v Microsoft .NET, určitě se podívejte na funkcionální programovací jazyk F#. F# vychází z jazyka OCaml který patří do rodiny funkcionálních jazyků ML, stejně jako již zmiňovaný jazyk Scala.

pátek, 30. října 2009

Programovací jazyk Scala - další funkcionální programovací jazyk pro JVM


(logo programovacího jazyka Scala ze http://www.scala-lang.org/)

V předminulém příspěvku jsem se zmiňoval o programovacím jazyce Clojure který je vlastně dialektem Lispu pro JVM.
Další funkcionálním programovacím jazykem pro Java Virtual Machine je Scala. Scala nevychází z Lispu ale z rodiny funkcionálních jazyků ML do které rovněž patří jazyky OCaml a Microsoft F#. Tyto jazyky pracují s rozsáhlejší syntaxí než Lisp a jsou v tomto ohledu podobnější "normálním" :-) programovacím jazykům.
Podobně jako Clojure i Scala kombinuje prvky funkcionálního programování s Javou. Z programu napsaného v jazyce Scala můžete jednoduše volat javovské třídy a ve Scale můžete implementovat třídu kterou bude používat javovský program.

Domácí stránka jazyka Scala: http://www.scala-lang.org/
Úvod do jazyka Scala v příkladech (pdf): http://www.scala-lang.org/docu/files/ScalaByExample.pdf
Úvod do jazyka Scala pro programátory v Javě (pdf): http://www.scala-lang.org/docu/files/ScalaTutorial.pdf

středa, 28. října 2009

Zrušení definice proměnné a funkce, aktuální adresář, změna adresáře



Zrušení definice proměnné: 
(setq a '(1 2 3)) 
a                              ; => (1 2 3)

(makunbound 'a)
a                              ;The variable A is unbound - proměnná už není definována


Zrušení definice funkce:
(defun f(x) (* 2 x))
(f 3)                         ; => 6
(fmakunbound 'f) 
(f 3)                         ;Undefined operator F - funkce už není definována

Aktuální adresář, změna aktuálního adresáře
(get-working-directory)   ; => #P"C:/Windows/system32/"

(change-directory "/honza/lisp/")

(get-working-directory)   ; => #P"/honza/lisp/"

pondělí, 26. října 2009

Zajímavý dialekt Lispu pro JVM - Clojure


(logo jazyka Clojure z http://clojure.org/)

Pokud vás Lisp zaujal ale jinak všechny své projekty programujete v Javě, pak by se vám mohl líbit Clojure - dialekt jazyka Lisp který běží nad Java Virtual Machine.
Programy které napíšete v Clojure se zkompilují do Java bytekódu a můžete je snadno kombinovat s programy v jazyce Java. A naopak, v Clojure máte k dispozici standardní knihovny Javy se všemi třídami na které jste zvyklí - Clojure je příjemný mix Javy a Lispu. (Jazyk Clojure není stejný jako Common Lisp, trochu se liší i syntakticky, ale základní myšlenky Lispu v něm najdete).

Domácí stránka programovacího jazyka Clojure http://clojure.org/
Rychlý úvod: http://clojure.org/getting_started
Přednáška autora jazyka Riche Hickeyho (video): http://www.infoq.com/presentations/hickey-clojure

Rozdíl mezi setf a setq

Pro definici a nastavování proměnných většinou používáme příkaz setf (přesněji řečeno, v hantýrce Lispu se mu říká makro setf nebo speciální forma setf).  
Setf je obecný příkaz který dokáže měnit hodnoty proměnných i hodnoty paměťových míst popsaných jiným způsobem, v Lispu se takovým paměťovým místům říká places.

sobota, 24. října 2009

Jak vznikly názvy cons, car a cdr (anglicky)



(obrázek z wikipedia.com)

Cituji ze starších materiálů JUI od Jana Lukeše:
The name of the cons function is not unreasonable: it is an abbreviation
of the word `construct'. The origins of the names for car and cdr, on the
other hand, are esoteric: car is an acronym from the phrase `Contents of
the Address part of the Register'; and cdr (pronounced `could-er') is an
acronym from the phrase `Contents of the Decrement part of the Register'.
These phrases refer to specific pieces of hardware on the very early computer on which the original Lisp was developed. Besides being obsolete, the phrases have been completely irrelevant for more than 25 years to anyone thinking
about Lisp. Nonetheless, although a few brave scholars have begun to use
more reasonable names for these functions, the old terms are still in use.

Ještě k tomu dodám že zmíněným počítačem je IBM 704, to je to sálové "nepísíčko" na obrázku.

čtvrtek, 22. října 2009

Tahák ke Common Lispu


(obrázek z Wikipedia.com)


V dřívějším článku jsem zmínil Simplified Common Lisp reference od pana Trávníka, bývalého spolupracovníka X36JUI. Je to užitečná a stručná dokumentace která se čte se líp než rozsáhlá a vyčerpávající standardní dokumentace Common Lispu.

Další takový přehled ve formě stručného "taháku" zpracoval pan Jak Lukeš, rovněž bývalý cvičící X36JUI. Pana Trávníka a pana Lukeše zdravím a děkuji jim za užitečné přehledy které v předmětu X36JUI připravili.

pondělí, 12. října 2009

99 lispových hádanek


(obrázek ze scieneer.com)

Na http://www.ic.unicamp.br/~meidanis/courses/mc336/2006s2/funcional/L-99_Ninety-Nine_Lisp_Problems.html najdete 99 hezkých hádanek z Lispu seřazených pěkně od nejjednodušších k nejsložitějším. Myslím že ten kdo si pro radost některé z nich vyřeší bude velmi dobře připraven na zápočtovou písemku ;-).

čtvrtek, 8. října 2009

Hrátky se zamotanými seznamy


(obrázek z wikipedia.com)

(Disclaimer: Následující článek považujte spíš za zajímavou hříčku než za příklad toho jak byste měli v Lispu pracovat se seznamy. Funkcionální styl programování dává přednost neměnným datovým strukturám, přesměrovávání ukazatelů v seznamu které v článku používáme může být z hlediska funkcionálního programování považováno za nečistý trik. Nicméně, i nečisté triky mohou být zábavné :-) 

Na dnešním cvičení jsem dostal zajímavý dotaz: Co se stane když v Lispu přesměruju cdr seznamu zpátky na jeho začátek?

Klávesové zkratky LispWorks ve Windows módu a v Emacs módu

Hezky zpracovaný seznam všech klávesových zkratek pro LispWorks ve Windows módu:
http://phoenix.inf.upol.cz/~dostal/data/0708/PP3/lw-windows.pdf

A ještě zkratky pro LispWorks v Emacs módu (výchozí mód LispWorks):
http://phoenix.inf.upol.cz/~dostal/data/0708/PP3/lw-emacs.pdf

Doplnění: V seznamu klávesových zkratek pro Windows chybí užitečná zkratka Shift+F8 - vyhodnocení posledního výrazu a zobrazení výsledku v dolním řádku, to samé co na cvičeních dělám v Emacs módu klávesami Ctrl-X Ctrl-E.

Klávesa 'Meta' v Emacs módu odpovídá klávese Escape a ve Windows módu klávese Ctrl-M.

Módy se přepínají v "Tools - Preferences - Emulation - Editor keys like Microsoft Windows".

(Autorem dokumentů je pan Dostál z UPOL Olomouc)

úterý, 6. října 2009

Tail-recursion

Častým tématem je v Lispu převod rekurzivního programu do podoby která využívá tail-recursion (a nedivil bych se kdyby cvičící nějaký takový příklad zařadili i do písemky ;-)

Podívejme se na funkci která vrátí počet výskytů prvku v seznamu:

(defun kolikrat(x S)
  (cond ((null S) 0)
        ((eql x (car S)) (1+ (kolikrat x (cdr S))))
        (T (kolikrat x (cdr S)))))


(kolikrat 4 '(1 2 3 4 5 1 2 3 4 5)) ;vrací  2

Common Lisp - dokumentace

V LispWorks můžete klávesami Ctrl-Shift-D a Enter vyvolat online nápovědu k funkci na které je právě kurzor. Tato funkce vyhledá daný symbol v souborech nápovědy které se instalují společně s LispWorks.

Pro standardní funkce se pak typicky zobrazí stránka z Common Lisp HyperSpec, což je velmi podrobná dokumentace ke všem standardním funkcím. Společnost LispWorks jí má i na webu  http://www.lispworks.com/documentation/HyperSpec/Front/ .
Dokumentace není vázána jen na LispWorks, Common Lisp je standard a HyperSpec tedy platí i pro další implementace Lispu.

HyperSpec je velmi podrobný a je tedy vhodný pro hledání konkrétní funkce u které znáte název, není ale příliš vhodný jako studijní materiál. Pokud si chcete udělat přehled o nejdůležitějších standardních funkcích, přečtěte si výbornou Simplified Common Lisp reference od pana Trávníka, bývalého spolupracovníka X36JUI.

neděle, 4. října 2009

Tipy pro LispWorks

  • Klávesové zkratky v Listeneru a Editoru: 
    • Ctrl-A začátek řádky
    • Ctrl-E konec řádky
    • Ctrl-Space označit začátek regionu
    • Esc-W Copy
    • Ctrl-Y Paste
    • Esc-P předchozí příkaz
    • Esc-N následující příkaz
    • Esc-Ctrl-I doplňuje název symbolu podle počátečních písmen (ze standardních i z vámi definovaných funkcí)
  • Pokud vám nevyhovují tyto klávesové zkratky a'la Emacs, přepněte si na klávesové zkratky podle Windows: Tools - Preferences - Emulation - Editor keys like Microsoft Windows.
  • Ctrl-Tab přepíná z Editoru do Listeneru a zpět
  • Kompilace kódu v Editoru má klávesovou zkratku Ctlr-Shift-B (Compile Buffer)
  • V Editoru můžete rychle otestovat hodnotu výrazu bez přepínání do Listeneru
    • Ctrl-X Ctrl E (Evaluate Last Form) 
    • nebo označit začátek region (Ctrl-Space) a pak Ctrl-Shift-E (Evaluate Region)

sobota, 3. října 2009

Články a knihy o Lispu a Scheme

Na Rootu kdysi vyšly dva stručné a pěkné články o Lispu:
http://www.root.cz/clanky/jemny-uvod-do-lispu/
http://www.root.cz/clanky/lispova-makra-aneb-programovatelny-programovaci-jazyk/

Krásný komiksový tutorial Lispu ve kterém se krok za krokem programuje textová hra typu MUD:
http://www.lisperati.com/casting.html

Tutoriál Lispu který zmiňuje základní i pokročilejší témata
http://abhishek.geek.nz/docs/features-of-common-lisp

Knihy o Common Lispu
Practical Common Lisp
On Lisp

Knihy o Scheme (další dialekt jazyka Lisp)
Structure and Interpretation of Computer Programs
Programming Languages: Application and Interpretation