-
121. Data: 2019-01-10 14:22:18
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: g...@g...com
W dniu czwartek, 10 stycznia 2019 14:02:42 UTC+1 użytkownik AK napisał:
> > No, można i tak.
>
> Ano mozna.
> Zwlaszcza, ze jest to zgodne ze z podstawowa logika i
> specyfika Pythona (metkowanie).
A jaka jest "podstawowa logika i specyfika Pythona",
z której by ta zgodność wynikała?
> Kwestia czy zle (przylaczam sie do twierdzenia ze jest to mylace,
> - choc wylacznie dla poczatkujacych), czy dobrze (przy rekurencji
> przydatne czesto) jest dyskusyjna.
To może podaj kilka argumentów na rzecz takiego rozwiązania
(bo ja serio nie widzę żadnego)
> PS: Innym podejsciam jest zastosowanie czegos w rodzaju:
>
> def f(x=on_the_call(None)):
> return x
Czyli mamy co najmniej dwa złe idiomy zamiast jednego dobrego rozwiązania.
-
122. Data: 2019-01-10 15:47:13
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: AK <n...@n...net>
On 2019-01-10 14:22, g...@g...com wrote:
> W dniu czwartek, 10 stycznia 2019 14:02:42 UTC+1 użytkownik AK napisał:
>
>>> No, można i tak.
>>
>> Ano mozna.
>> Zwlaszcza, ze jest to zgodne ze z podstawowa logika i
>> specyfika Pythona (metkowanie).
>
> A jaka jest "podstawowa logika i specyfika Pythona",
> z której by ta zgodność wynikała?
Metkowanie.
1. Obiekty w Pythonie sa wylacznie "metkowane".
Kopiowane sa wylacznie prymitywy (int , float, bool i.. i chyba tyle).
2. definicja funkcji to jest _statement_ wiec wszystko co podlega
ewaluacji, jest _wlasnie wtedy_ ewaluowane.
Stad wartosci domyslne sa ewaluowane w momencie wykonania
_statementu_ def function().
>> Kwestia czy zle (przylaczam sie do twierdzenia ze jest to mylace,
>> - choc wylacznie dla poczatkujacych), czy dobrze (przy rekurencji
>> przydatne czesto) jest dyskusyjna.
>
> To może podaj kilka argumentów na rzecz takiego rozwiązania
> (bo ja serio nie widzę żadnego)
W rekurencji latwo zapamietac jakas "sciezke" wlasnie w takim
parametrze.
No ale przyklad z tej dyskusji.
pierwsze = [2]
def jest_pierwsza(liczba, pierwsze=pierwsze):
erasto = int(sqrt(liczba) + 0.5)
czy_pierwsza = all(liczba % pierwsza for pierwsza in pierwsze
if pierwsza <= erasto)
if czy_pierwsza: pierwsze.append(liczba)
return czy_pierwsza
Mozna zapisac tak:
def jest_pierwsza(liczba, pierwsze=[2]):
erasto = int(sqrt(liczba) + 0.5)
czy_pierwsza = all(liczba % pierwsza for pierwsza in pierwsze
if pierwsza <= erasto)
if czy_pierwsza: pierwsze.append(liczba)
return czy_pierwsza
Po co tworzyc niepotrzebnie globala/statica jesli jest on potrzebny
tylko wewnetrznie?
Jak wiadomo Python nie posiada takiej konstrukcji zmiennych/obiektow
statycznych funkcji w takim sensie jak C
int fun()
{
static int = 3;
}
wiec w ten sposob tworzy sie w Pythonie wlasnie zmienne statyczne
nie zasmiecajac wyzszego namespace.
>> PS: Innym podejsciam jest zastosowanie czegos w rodzaju:
>>
>> def f(x=on_the_call(None)):
>> return x
>
> Czyli mamy co najmniej dwa złe idiomy zamiast jednego dobrego rozwiązania.
Dlaczego zle ?
Nie widze w nich nic zlego.
Zwlaszcza w stosunku do expr w takim Lisp gdzie nawet priorytet
opeatorow poszedl do kosza wiec trzeba go wymuszac odpowiednia
kolejnoscia ewaluacji i/lub nawiasami (a nawet trzeba wymuszac/okreslac
tymiz lewo-prawo-lacznosc operatorow).
Np: (* A (* B (* C D))) to co innego niz (* (* (* C D) B) A)
Przecie to nieskonczone zrodlo pomylek.
PS: Tylko mi nie probuj mowic, ze jest inaczej bo drzewiej
pisywalem (fakt ze rzadko, nie umialem sie przekonac:) w AutoLispie
makra do AutoCADa "cus tam" liczace i... to dla numeryka byl
istny koszmar :(
W porzadnych jezykach programowania kolejnosc obliczania expr. byla
zawsze od lewa do prawa, a priorytet operatorow jest scisle okreslony
i dla arytmetycznych zgodny z normalna matematyka.
Oczywiscie C/C++ to popsul bo w nim stwierdzono (z wydumanych wzgledow
wydajnosciowych oczywscie:) ze kolejnosc ewaluacji czesci wyrazen jest
.. dowolna co rowniez jest zrodlem niekiedy koszmarow (gdy
funckcje maja efekty uboczne - a miewaja czesciej niz sie wydaje:).
PS: Nawiasy nie pomoga. Nawiasy w C/C++ wymuszaja priorytety, ale nie
kolejnosc ewaluacji wyrazen.
Np takie cus w Algolu, Pascalu, Fortranie, PL/I, Javie, C# czy innym
Pythonie:
double y = 3;
double fun(double x)
{
y += x;
return y;
}
z = 2 * fun(3) + fun(7);
byloby jednoznaczne (wynik 25), ale juz w C/C++ moze to byc
albo 25 albo 36 (zaleznie od kierunku wiatru, kompilatora,
gestosci Slonca, % w nalewce Szwagra itp).
AK
-
123. Data: 2019-01-11 07:57:35
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: Maciej Sobczak <s...@g...com>
> Uważam, że problemem jest to, że masz dwie dopuszczalne
> interpretacje
No właśnie. I to jest ten błąd w języku. Więc zróbmy tak, żeby była tylko jedna, np.
taka:
y = x
update y
assert(y != y'old => x != y)
To powyżej czasem działa a czasem nie działa, zależnie od tego jaki typ się trafi.
Tymczasem dla mnie powyższy zapis jest generyczny, jest czymś w rodzaju aksjomatu i
powinno działać zawsze. Albo, jeśli wolisz, nigdy (ale wtedy marnie widzę
programowanie w takim języku). W przeciwnym razie nie wiem, na czym stoję.
--
Maciej Sobczak * http://www.inspirel.com
-
124. Data: 2019-01-11 08:05:58
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: Maciej Sobczak <s...@g...com>
> Otoz da sie wyjasnic bardzo latwo wlasnie na podstawie specyfikacji Py.
> Tak bedzie rowniez w Py3.8+
To poproszę to wyjaśnienie, bo coś Ci post urwało.
> Heh :) Zabawka to jest Wolfram (jako jezyk - nie srodowisko).
> Trudno mi sobie wybarazic dziesiejszy jezyk programowania ktory
> nie posiada obiektow
Po pierwsze, to żaden dzisiejszy język programowania nie jest dzisiejszy a po drugie,
chyba nie czytałeś postów Godka.
> Przypominam ze watek jest o jezyky programowania dla poczatkuacych :)
I w żadnym poście tutaj nikt jeszcze nie sugerował, że taki język ma być obiektowy.
Co ciekawe, nikt też jeszcze nie sugerował, że język dla zaawansowanych też powinien
być.
Wolfram nie jest obiektowy, bo miał nie być. Ale przynajmniej jak zmieniam w nim
kopię jakiegoś obiektu (sic!), to zmienia się kopia a nie oryginał.
--
Maciej Sobczak * http://www.inspirel.com
-
125. Data: 2019-01-11 19:14:32
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: g...@g...com
W dniu czwartek, 10 stycznia 2019 15:47:22 UTC+1 użytkownik AK napisał:
> >>> No, można i tak.
> >>
> >> Ano mozna.
> >> Zwlaszcza, ze jest to zgodne ze z podstawowa logika i
> >> specyfika Pythona (metkowanie).
> >
> > A jaka jest "podstawowa logika i specyfika Pythona",
> > z której by ta zgodność wynikała?
>
> Metkowanie.
> 1. Obiekty w Pythonie sa wylacznie "metkowane".
> Kopiowane sa wylacznie prymitywy (int , float, bool i.. i chyba tyle).
Tzn. przekazywane przez referencję?
> 2. definicja funkcji to jest _statement_ wiec wszystko co podlega
> ewaluacji, jest _wlasnie wtedy_ ewaluowane.
> Stad wartosci domyslne sa ewaluowane w momencie wykonania
> _statementu_ def function().
A jakie są pozostałe "statementy"?
> >> Kwestia czy zle (przylaczam sie do twierdzenia ze jest to mylace,
> >> - choc wylacznie dla poczatkujacych), czy dobrze (przy rekurencji
> >> przydatne czesto) jest dyskusyjna.
> >
> > To może podaj kilka argumentów na rzecz takiego rozwiązania
> > (bo ja serio nie widzę żadnego)
>
> W rekurencji latwo zapamietac jakas "sciezke" wlasnie w takim
> parametrze.
>
> No ale przyklad z tej dyskusji.
>
> pierwsze = [2]
> def jest_pierwsza(liczba, pierwsze=pierwsze):
> erasto = int(sqrt(liczba) + 0.5)
> czy_pierwsza = all(liczba % pierwsza for pierwsza in pierwsze
> if pierwsza <= erasto)
> if czy_pierwsza: pierwsze.append(liczba)
> return czy_pierwsza
>
> Mozna zapisac tak:
>
> def jest_pierwsza(liczba, pierwsze=[2]):
> erasto = int(sqrt(liczba) + 0.5)
> czy_pierwsza = all(liczba % pierwsza for pierwsza in pierwsze
> if pierwsza <= erasto)
> if czy_pierwsza: pierwsze.append(liczba)
> return czy_pierwsza
>
> Po co tworzyc niepotrzebnie globala/statica jesli jest on potrzebny
> tylko wewnetrznie?
> Jak wiadomo Python nie posiada takiej konstrukcji zmiennych/obiektow
> statycznych funkcji w takim sensie jak C
>
> int fun()
> {
> static int = 3;
> }
>
> wiec w ten sposob tworzy sie w Pythonie wlasnie zmienne statyczne
> nie zasmiecajac wyzszego namespace.
Można też użyć do tego celu "domknięcia", albo klasy.
Przekazanie parametru rekurencyjnie do funkcji to nic trudnego
> >> PS: Innym podejsciam jest zastosowanie czegos w rodzaju:
> >>
> >> def f(x=on_the_call(None)):
> >> return x
> >
> > Czyli mamy co najmniej dwa złe idiomy zamiast jednego dobrego rozwiązania.
>
> Dlaczego zle ?
> Nie widze w nich nic zlego.
Sam powiedziałeś, że "bywa mylące".
Ja uważam, że jest mylące z dobrych powodów.
> Zwlaszcza w stosunku do expr w takim Lisp gdzie nawet priorytet
> opeatorow poszedl do kosza wiec trzeba go wymuszac odpowiednia
> kolejnoscia ewaluacji i/lub nawiasami (a nawet trzeba wymuszac/okreslac
> tymiz lewo-prawo-lacznosc operatorow).
> Np: (* A (* B (* C D))) to co innego niz (* (* (* C D) B) A)
> Przecie to nieskonczone zrodlo pomylek.
?
Jakich pomyłek?
W każdym języku f(x, f(y, f(z, w))) to raczej coś innego niż
f(f(f(z, w), y, x).
I to nie jest "wymuszanie nawiasami lewo-prawo-łączności operatorów",
bo w Lispie syntaktyczine w ogóle nie ma czegoś takiego.
Akurat operator mnożenia jest (semantycznie) łączny i przemienny,
toteż nie ma znaczenia, czy napiszesz tak, czy inaczej.
Możesz też napisać (* A B C D) albo (* C D B A).
> PS: Tylko mi nie probuj mowic, ze jest inaczej bo drzewiej
> pisywalem (fakt ze rzadko, nie umialem sie przekonac:) w AutoLispie
> makra do AutoCADa "cus tam" liczace i... to dla numeryka byl
> istny koszmar :(
Co ja mam Ci próbować wmówić?
Jak czegoś nie lubisz, to to Twoja sprawa.
> W porzadnych jezykach programowania kolejnosc obliczania expr. byla
> zawsze od lewa do prawa, a priorytet operatorow jest scisle okreslony
> i dla arytmetycznych zgodny z normalna matematyka.
Lepiej zamiast "normalna matematyka" powiedzieć
"matematyka, której mnie uczono".
> Oczywiscie C/C++ to popsul bo w nim stwierdzono (z wydumanych wzgledow
> wydajnosciowych oczywscie:) ze kolejnosc ewaluacji czesci wyrazen jest
> .. dowolna co rowniez jest zrodlem niekiedy koszmarow (gdy
> funckcje maja efekty uboczne - a miewaja czesciej niz sie wydaje:).
W "normalnej matematyce" funkcje nie mają efektów ubocznych.
> PS: Nawiasy nie pomoga. Nawiasy w C/C++ wymuszaja priorytety, ale nie
> kolejnosc ewaluacji wyrazen.
> Np takie cus w Algolu, Pascalu, Fortranie, PL/I, Javie, C# czy innym
> Pythonie:
> double y = 3;
> double fun(double x)
> {
> y += x;
> return y;
> }
> z = 2 * fun(3) + fun(7);
> byloby jednoznaczne (wynik 25), ale juz w C/C++ moze to byc
> albo 25 albo 36 (zaleznie od kierunku wiatru, kompilatora,
> gestosci Slonca, % w nalewce Szwagra itp).
No i bardzo dobrze.
Przynajmniej zniechęca ludzi do pisania takich programów.
-
126. Data: 2019-01-11 21:31:44
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: AK <n...@n...net>
On 2019-01-11 19:14, g...@g...com wrote:
> W dniu czwartek, 10 stycznia 2019 15:47:22 UTC+1 użytkownik AK napisał:
>
>> Metkowanie.
>> 1. Obiekty w Pythonie sa wylacznie "metkowane".
>> Kopiowane sa wylacznie prymitywy (int , float, bool i.. i chyba tyle).
>
> Tzn. przekazywane przez referencję?
Nie. To jednak nie jest to samo co referencja w C++ czy innej
Javie.
>
>> 2. definicja funkcji to jest _statement_ wiec wszystko co podlega
>> ewaluacji, jest _wlasnie wtedy_ ewaluowane.
>> Stad wartosci domyslne sa ewaluowane w momencie wykonania
>> _statementu_ def function().
>
> A jakie są pozostałe "statementy"?
Takie jak w manualu.
>>>> Kwestia czy zle (przylaczam sie do twierdzenia ze jest to mylace,
>>>> - choc wylacznie dla poczatkujacych), czy dobrze (przy rekurencji
>>>> przydatne czesto) jest dyskusyjna.
>>>
>>> To może podaj kilka argumentów na rzecz takiego rozwiązania
>>> (bo ja serio nie widzę żadnego)
>>
>> W rekurencji latwo zapamietac jakas "sciezke" wlasnie w takim
>> parametrze.
>>
>> No ale przyklad z tej dyskusji.
>>
>> pierwsze = [2]
>> def jest_pierwsza(liczba, pierwsze=pierwsze):
>> erasto = int(sqrt(liczba) + 0.5)
>> czy_pierwsza = all(liczba % pierwsza for pierwsza in pierwsze
>> if pierwsza <= erasto)
>> if czy_pierwsza: pierwsze.append(liczba)
>> return czy_pierwsza
>>
>> Mozna zapisac tak:
>>
>> def jest_pierwsza(liczba, pierwsze=[2]):
>> erasto = int(sqrt(liczba) + 0.5)
>> czy_pierwsza = all(liczba % pierwsza for pierwsza in pierwsze
>> if pierwsza <= erasto)
>> if czy_pierwsza: pierwsze.append(liczba)
>> return czy_pierwsza
>>
>> Po co tworzyc niepotrzebnie globala/statica jesli jest on potrzebny
>> tylko wewnetrznie?
>> Jak wiadomo Python nie posiada takiej konstrukcji zmiennych/obiektow
>> statycznych funkcji w takim sensie jak C
>>
>> int fun()
>> {
>> static int = 3;
>> }
>>
>> wiec w ten sposob tworzy sie w Pythonie wlasnie zmienne statyczne
>> nie zasmiecajac wyzszego namespace.
>
> Można też użyć do tego celu "domknięcia", albo klasy.
Po co ?
PS: Owszem, Przy wiekszej ilosci danych/atrybutow uzywa sie w Py klasy,
named tuple, slownika, domkniec itp itp.
> Przekazanie parametru rekurencyjnie do funkcji to nic trudnego
Po co przekazywac "z gory" jesli mozna to samo uzyskac
w lokalnym scope ? No po co ? Bo?
>>>> PS: Innym podejsciam jest zastosowanie czegos w rodzaju:
>>>>
>>>> def f(x=on_the_call(None)):
>>>> return x
>>>
>>> Czyli mamy co najmniej dwa złe idiomy zamiast jednego dobrego rozwiązania.
>>
>> Dlaczego zle ?
>> Nie widze w nich nic zlego.
>
> Sam powiedziałeś, że "bywa mylące".
> Ja uważam, że jest mylące z dobrych powodów.
No jesli sie nie czyta wpierw nic o jezyku/manuali
to wszytsko bywa mylace :)
Poza tym to bardzo standardowe idiomy.
Wszedzie w Py spotykane.
>> Zwlaszcza w stosunku do expr w takim Lisp gdzie nawet priorytet
>> opeatorow poszedl do kosza wiec trzeba go wymuszac odpowiednia
>> kolejnoscia ewaluacji i/lub nawiasami (a nawet trzeba wymuszac/okreslac
>> tymiz lewo-prawo-lacznosc operatorow).
>> Np: (* A (* B (* C D))) to co innego niz (* (* (* C D) B) A)
>> Przecie to nieskonczone zrodlo pomylek.
> ?
> Jakich pomyłek?
> W każdym języku f(x, f(y, f(z, w))) to raczej coś innego niż
> f(f(f(z, w), y, x).
Tyle ze przy mnozeniu jest to to samo.
Chodzi o to ze trzeba ciagle pilnowac priorytetow operatorow
(czy kolejnisci) przez odpowednie konstrukcje - czyli na bakier
normalnej metematyce. Notacja Lisp akurat wyrazeniom arytmetycznym
wyraznie szkodzi i nie ma co tego tlumaczyc "elegancja" czy
"czystoscia" paradygmatow jezyka. To syf w uzyciu i tyle!
> I to nie jest "wymuszanie nawiasami lewo-prawo-łączności operatorów",
> bo w Lispie syntaktyczine w ogóle nie ma czegoś takiego.
> Akurat operator mnożenia jest (semantycznie) łączny i przemienny,
> toteż nie ma znaczenia, czy napiszesz tak, czy inaczej.
Ma znaczenie bo w jezykach programowania _istnieja efekty
uboczne_ i kolejnosc ewaluacji (od lewa do prawa) MA
znaczenie.
> Możesz też napisać (* A B C D) albo (* C D B A).
Moge. Tylko czy to wyglada na zapis matematyczny?
Toz to zwykla lista :)
>
>> PS: Tylko mi nie probuj mowic, ze jest inaczej bo drzewiej
>> pisywalem (fakt ze rzadko, nie umialem sie przekonac:) w AutoLispie
>> makra do AutoCADa "cus tam" liczace i... to dla numeryka byl
>> istny koszmar :(
>
> Co ja mam Ci próbować wmówić?
> Jak czegoś nie lubisz, to to Twoja sprawa.
Nie lubie dlatego, ze nie lubie.
Nie lubie, bo sprawia tak wiele niedogodnosci,
ze odciaga od domeny na rzecz młotka.
>
>> W porzadnych jezykach programowania kolejnosc obliczania expr. byla
>> zawsze od lewa do prawa, a priorytet operatorow jest scisle okreslony
>> i dla arytmetycznych zgodny z normalna matematyka.
>
> Lepiej zamiast "normalna matematyka" powiedzieć
> "matematyka, której mnie uczono".
Mnie uczono normalnej a nie (pre-post-s)fiksowanej.
>
>> Oczywiscie C/C++ to popsul bo w nim stwierdzono (z wydumanych wzgledow
>> wydajnosciowych oczywscie:) ze kolejnosc ewaluacji czesci wyrazen jest
>> .. dowolna co rowniez jest zrodlem niekiedy koszmarow (gdy
>> funckcje maja efekty uboczne - a miewaja czesciej niz sie wydaje:).
>
> W "normalnej matematyce" funkcje nie mają efektów ubocznych.
Programowanie "realne" to nie matematyka i efekty uboczne
sa "immanentna czescia" nie tylko C++.
W "moich czasach" nie mowilo sie "funkcje" ale "procedury".
Nazwe "funkcje" (intencjonalnie) zostawialo sie matematyce.
Algol/Simula"
integer procedure A()
begin
end
real procedure A()
begin
end
procedure C()
begin
end
>> PS: Nawiasy nie pomoga. Nawiasy w C/C++ wymuszaja priorytety, ale nie
>> kolejnosc ewaluacji wyrazen.
>> Np takie cus w Algolu, Pascalu, Fortranie, PL/I, Javie, C# czy innym
>> Pythonie:
>> double y = 3;
>> double fun(double x)
>> {
>> y += x;
>> return y;
>> }
>> z = 2 * fun(3) + fun(7);
>> byloby jednoznaczne (wynik 25), ale juz w C/C++ moze to byc
>> albo 25 albo 36 (zaleznie od kierunku wiatru, kompilatora,
>> gestosci Slonca, % w nalewce Szwagra itp).
>
> No i bardzo dobrze.
> Przynajmniej zniechęca ludzi do pisania takich programów.
Masz Ty pojecie o produkcyjnym rzemiosle?
Jesli mozna, to ludzie pisza zle i tyle.
Zaden jezyk przed tym nie uchroni, lecz powinien przynajmniej
zadbac, aby wyniki byly powtarzalne i nie zalezaly od kierunku wiatru.
Jezyki takie jak Algolu/Simula, Pascalu, Modula2, Fortran, PL/I, Java,
Python, C#, VB o to zadbaly. C++ nie.
AK
-
127. Data: 2019-01-11 22:42:25
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: g...@g...com
W dniu piątek, 11 stycznia 2019 21:31:56 UTC+1 użytkownik AK napisał:
> >> Metkowanie.
> >> 1. Obiekty w Pythonie sa wylacznie "metkowane".
> >> Kopiowane sa wylacznie prymitywy (int , float, bool i.. i chyba tyle).
> >
> > Tzn. przekazywane przez referencję?
>
> Nie. To jednak nie jest to samo co referencja w C++ czy innej
> Javie.
A czym się różni?
> >> 2. definicja funkcji to jest _statement_ wiec wszystko co podlega
> >> ewaluacji, jest _wlasnie wtedy_ ewaluowane.
> >> Stad wartosci domyslne sa ewaluowane w momencie wykonania
> >> _statementu_ def function().
> >
> > A jakie są pozostałe "statementy"?
>
> Takie jak w manualu.
Zobaczyłem w manual. Wprowadza rozróżnienie na "compound statement"
i "simple statement". Reguły, o której pisałeś wcześniej, nigdzie
nie znalazłem.
> >> wiec w ten sposob tworzy sie w Pythonie wlasnie zmienne statyczne
> >> nie zasmiecajac wyzszego namespace.
> >
> > Można też użyć do tego celu "domknięcia", albo klasy.
>
> Po co ?
> PS: Owszem, Przy wiekszej ilosci danych/atrybutow uzywa sie w Py klasy,
> named tuple, slownika, domkniec itp itp.
Po co ?
> > Przekazanie parametru rekurencyjnie do funkcji to nic trudnego
>
> Po co przekazywac "z gory" jesli mozna to samo uzyskac
> w lokalnym scope ? No po co ? Bo?
Globalnych obiektów lepiej unikać (zwłaszcza mutowalnych globalnych obiektów)
A jeżeli chce się już z nich korzystać, to lepiej wprowadzać je jawnie,
niż niejawnie i mimochodem.
> > Sam powiedziałeś, że "bywa mylące".
> > Ja uważam, że jest mylące z dobrych powodów.
>
> No jesli sie nie czyta wpierw nic o jezyku/manuali
> to wszytsko bywa mylace :)
Jest różnica pomiędzy "nie czyta się nic",
a "zagląda się w egzotyczne zakamarki".
Dobrze zaprojektowany język pozwala łatwo wywnioskować z pierwotnych reguł jakie
będzie zachowanie złożonych wyrażeń.
> >> Zwlaszcza w stosunku do expr w takim Lisp gdzie nawet priorytet
> >> opeatorow poszedl do kosza wiec trzeba go wymuszac odpowiednia
> >> kolejnoscia ewaluacji i/lub nawiasami (a nawet trzeba wymuszac/okreslac
> >> tymiz lewo-prawo-lacznosc operatorow).
> >> Np: (* A (* B (* C D))) to co innego niz (* (* (* C D) B) A)
> >> Przecie to nieskonczone zrodlo pomylek.
> > ?
> > Jakich pomyłek?
> > W każdym języku f(x, f(y, f(z, w))) to raczej coś innego niż
> > f(f(f(z, w), y, x).
>
> Tyle ze przy mnozeniu jest to to samo.
No to hyc:
octave> a = [ 1 2 3; 4 5 6 ]
octave> b = [ 7 ; 8 ; 9 ]
octave> a * b
ans =
50
122
octave> b * a
error: operator *: nonconformant arguments (op1 is 3x1, op2 is 2x3)
> Chodzi o to ze trzeba ciagle pilnowac priorytetow operatorow
> (czy kolejnisci) przez odpowednie konstrukcje - czyli na bakier
> normalnej metematyce.
"pilnować"?
Równie dobrze można by powiedzieć, że trzeba "pilnować kolejności wywołania
funkcji". No tak, na tym polega programowanie, że programista wie, co
chce napisać, i to pisze.
> Notacja Lisp akurat wyrazeniom arytmetycznym
> wyraznie szkodzi i nie ma co tego tlumaczyc "elegancja" czy
> "czystoscia" paradygmatow jezyka. To syf w uzyciu i tyle!
Ja nie miałem z tym nigdy problemu.
> > I to nie jest "wymuszanie nawiasami lewo-prawo-łączności operatorów",
> > bo w Lispie syntaktyczine w ogóle nie ma czegoś takiego.
> > Akurat operator mnożenia jest (semantycznie) łączny i przemienny,
> > toteż nie ma znaczenia, czy napiszesz tak, czy inaczej.
>
> Ma znaczenie bo w jezykach programowania _istnieja efekty
> uboczne_ i kolejnosc ewaluacji (od lewa do prawa) MA
> znaczenie.
Efekty uboczne nie istnieją "w językach programowania", tylko
w programach. (Co więcej, istnieją języki programowania, w których
efektów ubocznych nie ma)
> > Możesz też napisać (* A B C D) albo (* C D B A).
>
> Moge. Tylko czy to wyglada na zapis matematyczny?
> Toz to zwykla lista :)
To "iloczyn A B C i D".
Zresztą (+ (* a b) (/ c d)) to też
"suma iloczynu a z b oraz ilorazu c przez d".
Czyta się prawie tak samo, jak się pisze.
> >> PS: Tylko mi nie probuj mowic, ze jest inaczej bo drzewiej
> >> pisywalem (fakt ze rzadko, nie umialem sie przekonac:) w AutoLispie
> >> makra do AutoCADa "cus tam" liczace i... to dla numeryka byl
> >> istny koszmar :(
> >
> > Co ja mam Ci próbować wmówić?
> > Jak czegoś nie lubisz, to to Twoja sprawa.
>
> Nie lubie dlatego, ze nie lubie.
> Nie lubie, bo sprawia tak wiele niedogodnosci,
> ze odciaga od domeny na rzecz młotka.
Programuję w Lispie dużo, i nie mam takiego wrażenia.
Przeciwnie: to, że operacje matematyczne są mało poręczne
w użyciu, zachęca do nadawania nazw, przez co kod staje się
bliższy domenie. Np.
(define (euclid-distance x y)
(sqrt (apply + (map square (map - x y)))))
(define (average items)
(/ (apply + items)
(length items)))
itd.
> >> Oczywiscie C/C++ to popsul bo w nim stwierdzono (z wydumanych wzgledow
> >> wydajnosciowych oczywscie:) ze kolejnosc ewaluacji czesci wyrazen jest
> >> .. dowolna co rowniez jest zrodlem niekiedy koszmarow (gdy
> >> funckcje maja efekty uboczne - a miewaja czesciej niz sie wydaje:).
> >
> > W "normalnej matematyce" funkcje nie mają efektów ubocznych.
>
> Programowanie "realne" to nie matematyka i efekty uboczne
> sa "immanentna czescia" nie tylko C++.
Ciekawe, że najpierw zarzucasz Lispowi, że notacja nie jest
"jak w normalnej matematyce", ale to, że Pythonowe funkcje nie
są "jak w normalnej matematyce", już jest OK.
Dlaczego pierwsze jest nie OK, a drugie jest OK?
> W "moich czasach" nie mowilo sie "funkcje" ale "procedury".
I ja jestem za tym.
(no i w językach w rodzaju Haskella też masz funkcje).
To, że C, a po nim JavaScript, PHP i inne języki, zawłaszczyło słowo
"funkcja", jest zdecydowanie mylące.
> > No i bardzo dobrze.
> > Przynajmniej zniechęca ludzi do pisania takich programów.
>
> Masz Ty pojecie o produkcyjnym rzemiosle?
> Jesli mozna, to ludzie pisza zle i tyle.
Jak są źle nauczeni, to piszą źle.
-
128. Data: 2019-01-14 09:36:34
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: Maciej Sobczak <s...@g...com>
[kolejność ewaluacji]
> Jezyki takie jak Algolu/Simula, Pascalu, Modula2, Fortran, PL/I, Java,
> Python, C#, VB o to zadbaly. C++ nie.
Ada też nie. Z tych samych powodów, co C++.
A ponieważ Ada i Pascal mają wspólne mianowniki, to sprawdziłem z ciekawości dla
Pascala:
https://www.freepascal.org/docs-html/ref/refch12.htm
l
"
The order in which expressions of the same precedence are evaluated is not guaranteed
to be left-to-right. In general, no assumptions on which expression is evaluated
first should be made in such a case. The compiler will decide which expression to
evaluate first based on optimization rules. Thus, in the following expression:
a := g(3) + f(2);
f(2) may be executed before g(3). This behaviour is distinctly different from Delphi
or Turbo Pascal.
"
Znaczy - nie masz racji co do Pascala, który w obrębie swojej rodziny sam ze sobą
jest w ten sprawie niespójny. Nie chce mi się sprawdzać dla innych języków, ale
nieustalona kolejność ewaluacji podwyrażeń jest czymś, co akceptuję jako naturalne,
ale nadal różne od tego:
a+b-c
vs:
a-c+b
W pozyższym chcę wiedzieć, że kolejność wykonania jest od lewej do prawej, bo to
sprawia, że te wyrażenia są jednak różne i mają różną dziedzinę.
Niemniej - jedna z rzeczy, które mi się podobają w Adzie to właśnie podział
podprogramów na procedury i funkcje. Procedur nie da się użyć w wyrażeniu a funkcje
muszą być w wyrażeniu. Język tego nie wymusza, ale naturalnie łatwiej wtedy o
konwencję, że funkcje robi się "czyste" a procedury zostawia się na te okazje, kiedy
efekty uboczne są celowe.
I przy okazji nie ma tego kuriozalnego pół-typu void, bo jest wtedy w ogóle
niepotrzebny.
--
Maciej Sobczak * http://www.inspirel.com
-
129. Data: 2019-01-14 09:47:48
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: g...@g...com
W dniu poniedziałek, 14 stycznia 2019 09:36:35 UTC+1 użytkownik Maciej Sobczak
napisał:
> Niemniej - jedna z rzeczy, które mi się podobają w Adzie to właśnie podział
podprogramów na procedury i funkcje. Procedur nie da się użyć w wyrażeniu a funkcje
muszą być w wyrażeniu.
W Haskellu jest (z grubsza) podobnie.
Tzn. tam wszystko jest funkcją, ale procedury są emulowane za pomocą typu IO, który
ma inne reguły kompozycji, niż zwykłe funkcje.
> Język tego nie wymusza, ale naturalnie łatwiej wtedy o konwencję, że funkcje robi
się "czyste" a procedury zostawia się na te okazje, kiedy efekty uboczne są celowe.
A dlaczego to jest dobre? ;]
-
130. Data: 2019-01-14 10:12:38
Temat: Re: Jaki język polecić początkującemu? - komentarz do artykułu w Programista 9/2018
Od: AK <n...@n...net>
On 2019-01-14 09:36, Maciej Sobczak wrote:
> [kolejność ewaluacji]
>
>> Jezyki takie jak Algolu/Simula, Pascalu, Modula2, Fortran, PL/I, Java,
>> Python, C#, VB o to zadbaly. C++ nie.
>
> Ada też nie. Z tych samych powodów, co C++.
> A ponieważ Ada i Pascal mają wspólne mianowniki, to sprawdziłem z ciekawości dla
Pascala:
>
> https://www.freepascal.org/docs-html/ref/refch12.htm
l
>
> "
> The order in which expressions of the same precedence are evaluated is not
guaranteed to be left-to-right. In general, no assumptions on which expression is
evaluated first should be made in such a case. The compiler will decide which
expression to evaluate first based on optimization rules. Thus, in the following
expression:
>
> a := g(3) + f(2);
> f(2) may be executed before g(3). This behaviour is distinctly different from
Delphi or Turbo Pascal.
> "
>
> Znaczy - nie masz racji co do Pascala,
Mam. Pisalem w (standardowym) Pascalu jeszce na Odrze i wiem co mowie.
Tak jest rowniez w ICL1900 Pascalu, Microsoft Pascalu, Turbo Pacalu i
Delphi, TopSpeed Pascalu czy NDP Pascalu (innych nie znam).
> który w obrębie swojej rodziny sam ze sobą jest w ten sprawie niespójny.
To wlasnie/po prostu FreePascal jest niezgodny ze standardem/spieprzony.
AK