eGospodarka.pl
eGospodarka.pl poleca

eGospodarka.plGrupypl.comp.programmingJaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
  • Data: 2019-01-03 22:21:25
    Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
    Od: g...@g...com szukaj wiadomości tego autora
    [ pokaż wszystkie nagłówki ]

    W dniu czwartek, 3 stycznia 2019 21:51:47 UTC+1 użytkownik fir napisał:
    > W dniu czwartek, 3 stycznia 2019 18:20:04 UTC+1 użytkownik g...@g...com
    napisał:
    > >
    > > Przykład, który lubię dawać na różnych prezentacjach, to program
    > > liczący sumę kwadratów początkowych siedmiu liczb pierwszych.
    > >
    > > Imperatywnie zapisalibyśmy go tak:
    > >
    > > 1: licznik := 7
    > > 2: liczba := 0
    > > 3: suma := 0
    > > 4: dopóki (licznik > 0):
    > > 5: jeżeli jest_pierwsza(liczba):
    > > 6: suma := suma + liczba^2
    > > 7: licznik := licznik - 1
    > > 8: liczba := liczba + 1
    > >
    > > i jeszcze musieli dopowiedzieć, że po wykonaniu programu
    > > wynik znajdziemy w zmiennej "suma".
    > >
    > > Natomiast przy podejściu funkcyjnym po prostu "formalizujemy"
    > > sformułowaine problemu: "suma kwadratów początkowych 7 liczb pierwszych"
    > > ma swoją strukturę gramatyczną, którą możemy uwypuklić, biorąc jednostki
    > > znaczeniowe w nawiasy:
    > >
    > > (suma (kwadraty (początkowe 7 liczby-pierwsze)))
    > >
    > > Teraz wystarczy nam wyjaśnić, co to jest (suma elementów)
    > > czym są (kwadraty elementów), co to jest (początkowe N elementy)
    > > i czym są liczby-pierwsze.
    > >
    > > To jest kod, który bardzo łatwo się komponuje, i który
    > > bardzo łatwo się czyta, testuje i analizuje (I nie trzeba wyjaśniać,
    > > gdzie należy szukać wyniku)
    > >
    > > wiadomo, że (o ile definicje pojęć są takie, jakich byśm oczekiwali) wyrażenie
    > >
    > > (suma (kwadraty (początkowe 7 liczby-pierwsze)))
    > >
    > > jest równoważne wyrażeniu
    > >
    > > (suma (kwadraty '(2 3 5 7 11 13)))
    > >
    > > które jest równoważne wyrażeniu
    > >
    > > (suma '(4 9 25 49 121 169))
    > >
    > > i tak dalej.
    > >
    > lol ale mozesz podac ten kod w lispie w postaci takiej kompletnosci jak ten
    przyklad w pseudkodzie, by to rzeczywiscie porownac?
    >
    > bo to jest raczej istotnie
    >
    >
    > w c taki programik nie wyglada zbyt tragicznie
    >
    >
    > int PoliczSumeParuPoczatkowychLiczbPierwszych(int ilu)
    > {
    >
    > int dodano_pierwszych =0;
    > int suma = 0;
    >
    > for(int i=0;;i++)
    > {
    > if(jest_liczba_pierwsza(i))
    > {
    > suma+=i*i;
    > dodano_pierwszych++;
    > if(dodano_pierwszych==ilu) return suma;
    > }
    > }
    > }
    >
    > to ze nie wydziela on etapow na podej pierwsze, podnies do kwadratu zsumuj wynika
    raczej z tego ze pisze sie to tak by dzialalo szybko.. jak ktos sie nie upiera by
    bylo tak szybko moze podzielic na te fazy
    >
    >
    > chetnie bym zobaczyl taki kompletny progamik w tym lispie scheme czy co to tam jest

    Ogólnie derywację tego programu mam dość dogłębnie opisaną
    w pierwszym rozdziale "Pamphletu":
    https://github.com/panicz/pamphlet/raw/master/pamphl
    et.pdf

    W praktyce zapisałbym go raczej np. tak (jeżeli język
    wspierałby leniwą ewaluację):

    (sum (map square (initial 7 (only prime? numbers))))

    gdzie "map", "only" i "initial" są zdefiniowane tak:

    (define (map f list)
    (if (null? list)
    '()
    ;else
    (cons (f (first list)) (map f (rest list)))))

    (define (initial n elements)
    (if (= n 0)
    '()
    ;else
    (cons (first elements) (initial (- n 1) (rest elements))))))

    (define (only satisfying? elements)
    (if (null? elements)
    '()
    ;else
    (if (satisfying? (first elements))
    (cons (first elements) (only satisfying? (rest elements)))
    ;else
    (only satisfying? (rest elements)))))

    W Haskellu może jest nieco zwięźlej i czytelniej:

    map f [] = []
    map f (h:t) = (f h):(map f t)

    initial 0 elements = []
    initial n (first:rest) = first:(initial (n-1) rest)

    only satisfying [] = []
    only satisfying (first:rest) = if (satisfying first)
    then first:(only satisfying rest)
    else only satisfying rest

    Teraz, w języku z leniwą ewaluacją możemy zbudować nieskończoną listę liczb:

    (define (numbers-from n)
    (cons n (numbers-from (+ n 1))))

    (define numbers (numbers-from 0))

    albo w Haskellu:

    numbersFrom n = n:(numbersFrom (n+1))

    numbers = numbersFrom 0

    Sumę definiujemy następująco:

    (define (sum list)
    (if (null? list)
    0
    ;else
    (+ (first list) (sum (rest list)))))

    albo w Haskellu:

    sum [] = 0
    sum (first:rest) = first + (sum rest)

    W jezyku bez leniwej ewaluacji jest nieco ciężej (ten wariant jest
    opisany w Pamphlecie)

    Jeżeli idzie o "wydajność", to kompilator Haskella wspiera technikę
    kompilacji zwaną "fuzją" albo "deforestacją", i efektywnie wynikowy
    kod będzie z grubsza równoważny temu, co Ty napisałeś (nie będą
    tworzone żadne dodatkowe struktury w pamięci, tylko będzie pętla
    iterująca po jakichś tam zmiennych)

Podziel się

Poleć ten post znajomemu poleć

Wydrukuj ten post drukuj


Następne wpisy z tego wątku

Najnowsze wątki z tej grupy


Najnowsze wątki

Szukaj w grupach

Eksperci egospodarka.pl

1 1 1

Wpisz nazwę miasta, dla którego chcesz znaleźć jednostkę ZUS.

Wzory dokumentów

Bezpłatne wzory dokumentów i formularzy.
Wyszukaj i pobierz za darmo: