Discussion:
"Najbardziej imponujący kod, jaki widziałem"
(Wiadomość utworzona zbyt dawno temu. Odpowiedź niemożliwa.)
g***@gmail.com
2019-07-30 13:58:03 UTC
Permalink
Hej,
gdyby ktoś był zainteresowany, to ostatnio opublikowałem na Quorze nieco przydługawy artykuł (czy może raczej "małą książkę"?) objaśniający technikę Friedmana i Byrda "uruchamiania ewaluatora od tyłu".

https://www.quora.com/Can-you-explain-to-non-coders-the-most-impressive-code-youve-seen/answer/Panicz-Godek

W ogólności pytanie "jaki jest najbardziej imponujący kod, jaki widziałeś" wydaje mi się ciekawe, więc jeśli ktoś tu ma jakieś swoje obserwacje na ten temat, z chęcią bym się dowiedział.

Pozdrawiam
dantes
2019-07-31 09:34:46 UTC
Permalink
Post by g***@gmail.com
Hej,
gdyby ktoś był zainteresowany, to ostatnio opublikowałem na Quorze nieco przydługawy artykuł (czy może raczej "małą książkę"?) objaśniający technikę Friedmana i Byrda "uruchamiania ewaluatora od tyłu".
https://www.quora.com/Can-you-explain-to-non-coders-the-most-impressive-code-youve-seen/answer/Panicz-Godek
W ogólności pytanie "jaki jest najbardziej imponujący kod, jaki widziałeś" wydaje mi się ciekawe, więc jeśli ktoś tu ma jakieś swoje obserwacje na ten temat, z chęcią bym się dowiedział.
Pozdrawiam
Najbrdziej imponujący kod (w pierwszej 10-ce):
emulator karty sim w asemblerze sprzed ery Comp128v1.
Roman Tyczka
2019-07-31 10:32:24 UTC
Permalink
Post by dantes
Post by g***@gmail.com
Hej,
gdyby ktoś był zainteresowany, to ostatnio opublikowałem na Quorze nieco przydługawy artykuł (czy może raczej "małą książkę"?) objaśniający technikę Friedmana i Byrda "uruchamiania ewaluatora od tyłu".
https://www.quora.com/Can-you-explain-to-non-coders-the-most-impressive-code-youve-seen/answer/Panicz-Godek
W ogólności pytanie "jaki jest najbardziej imponujący kod, jaki widziałeś" wydaje mi się ciekawe, więc jeśli ktoś tu ma jakieś swoje obserwacje na ten temat, z chęcią bym się dowiedział.
Pozdrawiam
emulator karty sim w asemblerze sprzed ery Comp128v1.
To jeśli chodzi o assembler to w latach dziewięćdziesiątych powstał program
muzyczny typu tracker o nazwie DigiBooster. Był to najbardziej zaawansowany
tracker na Amigę, a było ich wtedy wiele. Napisany przez dwóch braci z
Wrocławia. Kawał dobrego softu, np. Amiga hardwarowo miała 4 kanały
dżwiękowe, a DigiBooster pozwalał pracować na 128 kanałach, co było
ewenementem w tego typu sofcie.

Obecnie odkupiony i przepisany już na C.

http://www.digibooster.de/en/gallery.php


ps. fajne było to, że zgłaszałem chłopakom od DigiBoostera błędy i sugestie
co do rozwoju nowych wersji ...Pocztą Polską, to może być niewyobrażalne
dzisiaj :-)
--
pozdrawiam
Roman Tyczka
Borneq
2019-07-31 11:54:34 UTC
Permalink
Post by Roman Tyczka
To jeśli chodzi o assembler to w latach dziewięćdziesiątych powstał program
muzyczny typu tracker o nazwie DigiBooster. Był to najbardziej zaawansowany
tracker na Amigę, a było ich wtedy wiele. Napisany przez dwóch braci z
Wrocławia. Kawał dobrego softu, np. Amiga hardwarowo miała 4 kanały
dżwiękowe, a DigiBooster pozwalał pracować na 128 kanałach, co było
ewenementem w tego typu sofcie.
Obecnie odkupiony i przepisany już na C.
http://www.digibooster.de/en/gallery.php
Stare dzieje, gdy marzeniem był ZxSpectrum z interpreterem Basicem, i w
Bajtku był opisany ToBoS (https://pl.wikipedia.org/wiki/ToBoS-FP)
kompilator Basica do kodu maszynowego.
Duże wrażenie przykład wzoru na sinusa, gdzie zastosowano wielomiany
Czebyszewa, podczas gdy w Basicu był wyliczany ogólną metodą - szeregiem
z silniami,
Bischoop
2021-09-23 23:11:14 UTC
Permalink
Post by Roman Tyczka
Post by dantes
emulator karty sim w asemblerze sprzed ery Comp128v1.
To jeśli chodzi o assembler to w latach dziewięćdziesiątych powstał program
muzyczny typu tracker o nazwie DigiBooster. Był to najbardziej zaawansowany
tracker na Amigę, a było ich wtedy wiele. Napisany przez dwóch braci z
Wrocławia. Kawał dobrego softu, np. Amiga hardwarowo miała 4 kanały
dżwiękowe, a DigiBooster pozwalał pracować na 128 kanałach, co było
ewenementem w tego typu sofcie.
Obecnie odkupiony i przepisany już na C.
http://www.digibooster.de/en/gallery.php
ps. fajne było to, że zgłaszałem chłopakom od DigiBoostera błędy i sugestie
co do rozwoju nowych wersji ...Pocztą Polską, to może być niewyobrażalne
dzisiaj :-)
stare maszynki fajne byly. Teraz tak przypomnialem sobie te dema jakie
mozna bylo pozapuszczac. Grafa nie powalala ale dzwieki robily zajebisty
klimat.
U mnie nie Amiga ale Atari ST hulalo.
Czasy super, bajtki PCWorldy i tak jak piszesz, cokolwiek wyslac to
Poczta Polska, czasy przed internetowe :-)

--
Thank You
Bischoop

Maciej Sobczak
2019-07-31 12:59:27 UTC
Permalink
Post by g***@gmail.com
https://www.quora.com/Can-you-explain-to-non-coders-the-most-impressive-code-youve-seen/answer/Panicz-Godek
W ogólności pytanie "jaki jest najbardziej imponujący kod, jaki widziałeś" wydaje mi się ciekawe, więc jeśli ktoś tu ma jakieś swoje obserwacje na ten temat, z chęcią bym się dowiedział.
Przeczytałem. Najpierw formalności - nie spodobały mi się dwie uwagi już na samym początku tekstu:

"Don’t be surprised if understanding this answer would take you many days, weeks or even months."

Nikt nie będzie zaskoczony, bo jeśli ktoś miałby tego nie zrozumieć, to by po prostu nie doczytał. Czytanie długich tekstów jest niemodne, zwłaszcza takich, których się nie rozumie od razu. Trochę też wygląda to na założenie, że czytelnik nie kuma bazy - otóż samo pytanie do tego artykułu było skierowane do programistów (nie można być pod wrażeniem jakiegokolwiek kodu, nie rozumiejąc go), więc zakładanie, że ktoś będzie potrzebował miesięcy, żeby zrozumieć Twój wywód, jest aroganckie. Zwłaszcza ta część, że ktoś w ogóle poświęci miesiące swojego życia na tak zaszczytne zadanie jak próba zrozumienia akurat Twojego wywodu, z 40+ innych w tej samej dyskusji, spośród niezliczonej liczby takich dyskusji na niezliczonej liczbie portali dyskusyjnych. Realia publikowania na portalach społecznościowych są takie, że albo ktoś to od razu zrozumie, albo od razu oleje. Nikt nie będzie inwestował cennych miesięcy życia na zrozumienie akurat Twojego artykułu. Bez jaj.

"Frankly speaking, I’ve found most other answers here completely disappointing."

W takim razie, frankly speaking, sam się podsumowałeś tym wstępem.
I nie tylko dlatego, że dla wielu ludzi najbardziej imponujące są właśnie najprostsze olśnienia, takie programistyczne Zen, jak wcześniejszy artykuł z wieżami Hanoi w 3 linijkach. Poprzednim zdaniem postawiłeś się ponad swoimi czytelnikami a tym zdaniem postawiłeś się ponad autorami innych postów. I takie właśnie są dwa zdania z trzech z pierwszego paragrafu Twojego tekstu. Bez jaj. Nie zachęcasz w ten sposób do rzeczowej dyskusji.


A teraz konkretnie - technika faktycznie ciekawa, ale pomijając zupełnie podstawowy wykład z LISPa dałoby się to zmieścić w kilku procentach objętości.
Czy to ma realne zastosowania? Nie wiem. Może mieć - obecnie żywe są dyskusje na temat zastępowania różnych grup zawodowych przez AI i dla nas ciekawym pytaniem jest to, czy można zastąpić programistę. Ale chyba trend jest w kierunku innych technik. Ostatnio widziałem prezentację systemu asystenta programisty (w skrócie: podpowiadacz w edytorze, czyli tak jak w Twoim artykule), który działał na zasadzie deep learning z milionów plików źródłowych z GitHuba. Czyli "nauczył się" (cokolwiek to znaczy) czytając istniejący już kod a potem podpowiada programiście całe garście kodu do tego co chce zrobić. I mam wrażenie, że ML jest bardziej prawdopodobnym kierunkiem rozwoju dla takich systemów. Zaletą takiego podejścia jest to, że ML działa jednakowo dobrze na każdym języku programowania (w szczególności na tych najpopularniejszych), natomiast to co pokazałeś w swoim artykule działa tylko w LISPie.

Sam artykuł oczywiście, jak zwykle, zniechęca do LISPa. Jak ktoś już lubi ten język, to się będzie cieszył, ale też dla takiej publiczności nie było sensu takich podstaw wykładać. A jak ktoś nie lubi, to nie polubi. Ile można wciskać ludziom, że zagnieżdżone pary to dobra metoda na robienie list? Przecież to absurd.
W tym kontekście konsekwentnie bardziej podoba mi się podejście Wolframa, gdzie lista jest podstawową konstrukcją wspieraną przez język:

head[elem1, elem2, elem3, ...]

bez sztucznego (!) ograniczenia na liczbę elementów. Nie ma zagnieżdżeń, jeśli nie są potrzebne (ale mogą być, jeśli chcemy drzewa). W Wolframie fajny jest też pomysł na wbudowany symbol Nothing, który "znika" z sekwencji elementów, jeśli się gdzieś pojawi. Wtedy funkcję filtrującą "only" można zdefiniować tak:

only[condition_, list_] := Map[
Function[x,
If[condition[x], x, Nothing]
],
list
]

czyli mapujemy elementy na siebie albo na Nothing jeśli nie spełniają warunku, i wtedy, przykładowo:

only[EvenQ, {1, 2, 3, 4, 5, 6, 7}]

{2, 4, 6}

Oczywiście nikt by tak nie zrobił, bo są gotowe funkcje filtrujące, ale ten przykład pokazuje, że o listach można myśleć prosto. I wtedy poprzeczka przetwarzania struktur danych jest konsekwentnie niżej - więc zapewne Twoje przykłady z artykułu dałoby się zapisać dużo prościej, zamiast walczyć ze sztucznymi ograniczeniami języka. Zagnieżdżone pary? No daj spokój. Palce można połamać, zupełnie bez satysfakcji.

Inna rzecz - czy konstrukcja if musi być podstawową w LISPie? W Wolframie nie musi być, bo podstawą całego przetwarzania i tak jest pattern matching, czyli mogę sobie zdefiniować własnego ifa:

myIf[True, x_, y_] := x
myIf[False, x_, y_] := y

Chociaż to nie jest właściwe technicznie określenie, można to rozumieć jako przeciążanie funkcji na wartości pierwszego parametru.
To działa tak samo jak standardowy If, więc ten standardowy If nie musi być "magiczną" funkcją, tylko może być biblioteczną. I konsekwentnie można sobie tak zdefiniować inne warunkowe konstrukcje sterujące. LISP też tak umie, czy może musi mieć ifa jako "magiczną" funkcję interpretera, bez której niczego nie dało by się zrobić?
--
Maciej Sobczak * http://www.inspirel.com
Borneq
2019-07-31 14:18:18 UTC
Permalink
Post by Maciej Sobczak
prezentację systemu asystenta programisty (w skrócie: podpowiadacz w
edytorze, czyli tak jak w Twoim artykule), który działał na zasadzie
deep learning z milionów plików źródłowych z GitHuba. Czyli "nauczył
się" (cokolwiek to znaczy) czytając istniejący Już kod a potem
podpowiada programiście całe garście kodu do tego co chce zrobić.
I mam wrażenie, że ML jest bardziej prawdopodobnym kierunkiem rozwoju
dla takich systemów. Zaletą takiego podejścia jest to, że ML działa
jednakowo dobrze na każdym języku programowania (w szczególności na
tych najpopularniejszych), natomiast to co pokazałeś w swoim artykule
działa tylko w LISPie.
Jakieś namiary ?
Borneq
2019-07-31 14:36:27 UTC
Permalink
Post by Borneq
Post by Maciej Sobczak
prezentację systemu asystenta programisty (w skrócie: podpowiadacz w
edytorze, czyli tak jak w Twoim artykule), który działał na zasadzie
deep learning z milionów plików źródłowych z GitHuba. Czyli "nauczył
się" (cokolwiek to znaczy) czytając istniejący Już kod a potem
podpowiada programiście całe garście kodu do tego co chce zrobić.
I mam wrażenie, że ML jest bardziej prawdopodobnym kierunkiem rozwoju
dla takich systemów. Zaletą takiego podejścia jest to, że ML działa
jednakowo dobrze na każdym języku programowania (w szczególności na
tych najpopularniejszych), natomiast to co pokazałeś w swoim artykule
działa tylko w LISPie.
Jakieś namiary ?
Widzę tu dwie możliwości: jedna to podpowiadanie kodem, drugie to
potężna refaktoryzacja typu "wydziel x kodu jakąś klasę, odpowiednio
poprzenoś metody , zalezności mają być takie by się kompilowało"
Maciej Sobczak
2019-08-01 11:47:22 UTC
Permalink
Post by Borneq
Post by Maciej Sobczak
prezentację systemu asystenta programisty (w skrócie: podpowiadacz w
edytorze, czyli tak jak w Twoim artykule), który działał na zasadzie
deep learning
Jakieś namiary ?
https://www.theverge.com/2019/7/24/20708542/coding-autocompleter-deep-tabnine-ai-deep-learning-smart-compose
--
Maciej Sobczak * http://www.inspirel.com
g***@gmail.com
2019-07-31 17:03:38 UTC
Permalink
Post by Maciej Sobczak
Post by g***@gmail.com
https://www.quora.com/Can-you-explain-to-non-coders-the-most-impressive-code-youve-seen/answer/Panicz-Godek
W ogólności pytanie "jaki jest najbardziej imponujący kod, jaki widziałeś" wydaje mi się ciekawe, więc jeśli ktoś tu ma jakieś swoje obserwacje na ten temat, z chęcią bym się dowiedział.
"Don’t be surprised if understanding this answer would take you many days, weeks or even months."
Nikt nie będzie zaskoczony, bo jeśli ktoś miałby tego nie zrozumieć, to by po prostu nie doczytał.
Podejrzewam, że większość osób może być zaskoczona, ponieważ taki format odpowiedzi raczej rzadko zdarza się na Quorze.
Post by Maciej Sobczak
Czytanie długich tekstów jest niemodne, zwłaszcza takich, których się nie rozumie od razu. Trochę też wygląda to na założenie, że czytelnik nie kuma bazy - otóż samo pytanie do tego artykułu było skierowane do programistów (nie można być pod wrażeniem jakiegokolwiek kodu, nie rozumiejąc go), więc zakładanie, że ktoś będzie potrzebował miesięcy, żeby zrozumieć Twój wywód, jest aroganckie.
Aroganckie? Mnie napisanie tego tekstu zajęło kilka miesięcy, a zrozumienie podstawowych rzeczy - co najmniej kilka lat. Daniel Friedman stwierdził kiedyś, że zrozumienie opisanego przeze mnie silnika wnioskującego - kilkunastu linijek kodu - zajęło mu ponad rok.
Post by Maciej Sobczak
Zwłaszcza ta część, że ktoś w ogóle poświęci miesiące swojego życia na tak zaszczytne zadanie jak próba zrozumienia akurat Twojego wywodu, z 40+ innych w tej samej dyskusji, spośród niezliczonej liczby takich dyskusji na niezliczonej liczbie portali dyskusyjnych. Realia publikowania na portalach społecznościowych są takie, że albo ktoś to od razu zrozumie, albo od razu oleje. Nikt nie będzie inwestował cennych miesięcy życia na zrozumienie akurat Twojego artykułu. Bez jaj.
Tego nie mogę wiedzieć (i sądzę, że Ty też nie).
Ale dotychczasowe reakcje na artykuł były raczej przychylne, i wydają się sugerować, że określenie "nikt" to raczej spore niedoszacowanie.
Post by Maciej Sobczak
"Frankly speaking, I’ve found most other answers here completely disappointing."
W takim razie, frankly speaking, sam się podsumowałeś tym wstępem.
I nie tylko dlatego, że dla wielu ludzi najbardziej imponujące są właśnie najprostsze olśnienia, takie programistyczne Zen, jak wcześniejszy artykuł z wieżami Hanoi w 3 linijkach. Poprzednim zdaniem postawiłeś się ponad swoimi czytelnikami a tym zdaniem postawiłeś się ponad autorami innych postów.
Nie rozumiem, w jaki sposób "postawiłem się ponad swoimi czytelnikami".
Stwierdzając, że zrozumienie czegoś może zająć kilka miesięcy?
Pomijając kwestię, że owo "postawienie się ponad nimi" jest logicznie niewykonalne, bo nie mogę a priori powiedzieć, kto ten tekst przeczyta.

Zaś co do "stawiania się ponad autorami innych postów", to owszem, ja sam nie wyniosłem z ich lektury nic wartościowego. To mnie stawia w tym samym szeregu z ewentualnymi innymi czytelnikami, którzy mieli podobne odczucia.
Post by Maciej Sobczak
A teraz konkretnie - technika faktycznie ciekawa, ale pomijając zupełnie podstawowy wykład z LISPa dałoby się to zmieścić w kilku procentach objętości.
Chciałbym to zobaczyć.
Post by Maciej Sobczak
Czy to ma realne zastosowania? Nie wiem. Może mieć - obecnie żywe są dyskusje na temat zastępowania różnych grup zawodowych przez AI i dla nas ciekawym pytaniem jest to, czy można zastąpić programistę. Ale chyba trend jest w kierunku innych technik. Ostatnio widziałem prezentację systemu asystenta programisty (w skrócie: podpowiadacz w edytorze, czyli tak jak w Twoim artykule), który działał na zasadzie deep learning z milionów plików źródłowych z GitHuba. Czyli "nauczył się" (cokolwiek to znaczy) czytając istniejący już kod a potem podpowiada programiście całe garście kodu do tego co chce zrobić. I mam wrażenie, że ML jest bardziej prawdopodobnym kierunkiem rozwoju dla takich systemów.
No właśnie, wydaje mi się, że w owym dopowiedzeniu "cokolwiek to znaczy" jest pogrzebany pies.
Nie traktuję programowania jako "produkowania kodu", tylko jako precyzyjną formę wyrażania myśli. Żadne AI nie będzie raczej w stanie wyrazić moich myśli precyzyjniej, niż ja sam.
Post by Maciej Sobczak
Zaletą takiego podejścia jest to, że ML działa jednakowo dobrze na każdym języku programowania (w szczególności na tych najpopularniejszych), natomiast to co pokazałeś w swoim artykule działa tylko w LISPie.
To co pokazałem w swoim artykule to po prostu idea, którą najwygodniej wyrazić w Lispie. Kilka lat temu Will Byrd przyjechał do Poznania, gdzie na konferencji PolyConf pokazał tę technikę zaimplementowaną dla prostego języka imperatywnego:


Post by Maciej Sobczak
Sam artykuł oczywiście, jak zwykle, zniechęca do LISPa.
Powiedz coś więcej na ten temat. W jaki sposób zniechęca?
Post by Maciej Sobczak
Jak ktoś już lubi ten język, to się będzie cieszył, ale też dla takiej publiczności nie było sensu takich podstaw wykładać. A jak ktoś nie lubi, to nie polubi. Ile można wciskać ludziom, że zagnieżdżone pary to dobra metoda na robienie list? Przecież to absurd.
head[elem1, elem2, elem3, ...]
bez sztucznego (!) ograniczenia na liczbę elementów. Nie ma zagnieżdżeń, jeśli nie są potrzebne (ale mogą być, jeśli chcemy drzewa).
Nie rozumiem. Jakiego ograniczenia na liczbę elementów?
Post by Maciej Sobczak
only[condition_, list_] := Map[
Function[x,
If[condition[x], x, Nothing]
],
list
]
only[EvenQ, {1, 2, 3, 4, 5, 6, 7}]
{2, 4, 6}
A co jeśli owa wartość Nothing miałaby zostać przekazana jako argument do funkcji?
Post by Maciej Sobczak
Oczywiście nikt by tak nie zrobił, bo są gotowe funkcje filtrujące, ale ten przykład pokazuje, że o listach można myśleć prosto.
No bo o listach można myśleć prosto?
Post by Maciej Sobczak
I wtedy poprzeczka przetwarzania struktur danych jest konsekwentnie niżej - więc zapewne Twoje przykłady z artykułu dałoby się zapisać dużo prościej, zamiast walczyć ze sztucznymi ograniczeniami języka. Zagnieżdżone pary? No daj spokój. Palce można połamać, zupełnie bez satysfakcji.
W kilku miejscach - tam, gdzie poziom zagnieżdżeń przesłaniał istotę rzeczy - użyłem notacji Haskella.
Post by Maciej Sobczak
myIf[True, x_, y_] := x
myIf[False, x_, y_] := y
Chociaż to nie jest właściwe technicznie określenie, można to rozumieć jako przeciążanie funkcji na wartości pierwszego parametru.
To działa tak samo jak standardowy If, więc ten standardowy If nie musi być "magiczną" funkcją, tylko może być biblioteczną. I konsekwentnie można sobie tak zdefiniować inne warunkowe konstrukcje sterujące. LISP też tak umie, czy może musi mieć ifa jako "magiczną" funkcję interpretera, bez której niczego nie dało by się zrobić?
To o co pytasz to absolutne podstawy lambda-rachunku.
If jest definiowalny w oparciu o lambda-wyrażenia. Zamieściłem go jako część ekspozycji, ponieważ wydaje mi się łatwy do zrozumienia dla "nie-programistów".

https://www.cl.cam.ac.uk/teaching/Lectures/funprog-jrh-1996/all.pdf
rozdział 3

Inna rzecz - czy pattern matching musi być podstawą w Wolframie? W LISPie nie musi być, i jeśli chcesz, możesz sobie zdefiniować swój własny.
Maciej Sobczak
2019-08-01 12:26:25 UTC
Permalink
Post by g***@gmail.com
Post by Maciej Sobczak
A teraz konkretnie - technika faktycznie ciekawa, ale pomijając zupełnie podstawowy wykład z LISPa dałoby się to zmieścić w kilku procentach objętości.
Chciałbym to zobaczyć.
Usuń z artykułu ten wykład o podstawach LISPa i zobacz, co zostało. Np. po co tłumaczyć ludziom, że operatory and i or można zaimplementować przy użyciu konstrukcji if? Generalnie - niepotrzebna dłużyzna.
Post by g***@gmail.com
Żadne AI nie będzie raczej w stanie wyrazić moich myśli precyzyjniej, niż ja sam.
I znowu myślenie egocentryczne. Problem z AI nie polega na tym, że zrobi coś lepiej od nas, tylko że nasza robota nie będzie potrzebna i konsekwentnie nasze zdanie o naszej indywidualnej wyższości nad jakimś tam AI nikogo nie będzie interesować.
Tzn. dzięki AI programowanie może zostać zepchnięte do roli hobby albo cepelii, tak jak np. ręcznie dziergane szaliki albo inna ceremika rekreacyjna.

Natomiast co do prezycji myśli - bez przesady, akurat w tej dziedzinie nie błyszczymy. Niektórzy uważają, że właśnie brak precyzji pozwolił nam przetrwać i ewoluować ("we would never survive if we weren't a bit crazy"), ale akurat w dziedzinach formalnych to nas raczej ogranicza.
Post by g***@gmail.com
To co pokazałem w swoim artykule to po prostu idea, którą najwygodniej wyrazić w Lispie.
Konsekwentnie się nie zgadzam, z racji tego, że w LISPie w ogóle mało co się wygodnie wyraża. Zagnieżdżone pary? Rekurencja? Daj spokój.
Post by g***@gmail.com
Post by Maciej Sobczak
Sam artykuł oczywiście, jak zwykle, zniechęca do LISPa.
Powiedz coś więcej na ten temat. W jaki sposób zniechęca?
Cytaty:

"Aren't all those closing parentheses beautiful?"
"The heavily parenthesized syntax of LISP may not be particularly readable."
Post by g***@gmail.com
Nie rozumiem. Jakiego ograniczenia na liczbę elementów?
Wykład o LISPie zawsze kładzie nacisk na to, że albo mam jeden obiekt albo parę. I że jak chcę czegoś więcej, to jest to jakaś rzeźba z par. To nie jest ograniczenie? A potem się okazuje, że zmiana N-tego elementu wymaga rekurencji. Oczywiście, można to wszystko ukryć pod przystępnymi funkcjami bibliotecznymi, ale po co przykrywać problem, którego można po prostu nie mieć?
Post by g***@gmail.com
A co jeśli owa wartość Nothing miałaby zostać przekazana jako argument do funkcji?
Na to też są sposoby, bo w takich specjalnych przypadkach można sterować dokładnym czasem ewaluacji. Niemniej, pytanie jest zasadne, ale zawsze można też odpowiedzieć, że można udawać, że takiego ficzeru w ogóle nie ma (tak jak go nie ma w innych językach), wtedy też nie powstaje problem z przekazywaniem Nothing jako parametr.
Post by g***@gmail.com
W kilku miejscach - tam, gdzie poziom zagnieżdżeń przesłaniał istotę rzeczy - użyłem notacji Haskella.
Rozumiem. Czyli do programowania w LISPie potrzeby jest Haskell, żeby przekazać czytelnikowi o co chodzi w LISPowym kodzie.
Właśnie takie efekty mam na myśli.
Post by g***@gmail.com
Post by Maciej Sobczak
Inna rzecz - czy konstrukcja if musi być podstawową w LISPie?
To o co pytasz to absolutne podstawy lambda-rachunku.
https://www.cl.cam.ac.uk/teaching/Lectures/funprog-jrh-1996/all.pdf
rozdział 3
OK, czyli nie musi.
Ale żeby prawda i fałsz musiały wtedy być funkcjami? Daj spokój.
Post by g***@gmail.com
Inna rzecz - czy pattern matching musi być podstawą w Wolframie?
Tak działa ewaluacja w Wolframie (to się nazywa "term rewriting": https://en.wikipedia.org/wiki/Rewriting). To podstawowy mechanizm, i tak dobrze udaje inne mechanizmy, że większość ludzi o nim zapomina, sądząc, że to jest po prostu "normalny wieloparadygmatowy język programowania".
--
Maciej Sobczak * http://www.inspirel.com
g***@gmail.com
2019-08-01 14:29:40 UTC
Permalink
Post by Maciej Sobczak
Post by g***@gmail.com
Post by Maciej Sobczak
A teraz konkretnie - technika faktycznie ciekawa, ale pomijając zupełnie podstawowy wykład z LISPa dałoby się to zmieścić w kilku procentach objętości.
Chciałbym to zobaczyć.
Usuń z artykułu ten wykład o podstawach LISPa i zobacz, co zostało. Np. po co tłumaczyć ludziom, że operatory and i or można zaimplementować przy użyciu konstrukcji if? Generalnie - niepotrzebna dłużyzna.
Dla jednych potrzebna, dla innych niepotrzebna.
Generalnie ludzie uczą się języka czytając przykłady, a nie reguły.
Jeżeli kogoś to nudzi, to łatwo sobie przeskoczy do kolejnego akapitu.
Post by Maciej Sobczak
Post by g***@gmail.com
Żadne AI nie będzie raczej w stanie wyrazić moich myśli precyzyjniej, niż ja sam.
I znowu myślenie egocentryczne. Problem z AI nie polega na tym, że zrobi coś lepiej od nas, tylko że nasza robota nie będzie potrzebna i konsekwentnie nasze zdanie o naszej indywidualnej wyższości nad jakimś tam AI nikogo nie będzie interesować.
Nasza robota nigdy nie była potrzebna.
No chyba że robisz w rolnictwie, czy ewentualnie budowlance.
Post by Maciej Sobczak
Tzn. dzięki AI programowanie może zostać zepchnięte do roli hobby albo cepelii, tak jak np. ręcznie dziergane szaliki albo inna ceremika rekreacyjna.
Ostatnio natrafiłem na ciekawy wywiad z Jackiem Dukajem, ocierający nieco o ten temat:

Post by Maciej Sobczak
Natomiast co do prezycji myśli - bez przesady, akurat w tej dziedzinie nie błyszczymy. Niektórzy uważają, że właśnie brak precyzji pozwolił nam przetrwać i ewoluować ("we would never survive if we weren't a bit crazy"), ale akurat w dziedzinach formalnych to nas raczej ogranicza.
Brak precyzji jest cechą charakterystyczną języka naturalnego (i w pewnej mierze języka matematyki).
Jest to cecha, której w pewnej mierze oczekujemy po języku naturalnym (nawet jeśli nie zawsze zdajemy sobie z tego sprawę).
Notacje formalne mają cel przeciwny - uczą dyscypliny bardzo rygorystycznego wyrażania się. Próby formalizacji języka naturalnego zawsze zawodzą (i m.in. dlatego np. język Inform 7 raczej nigdy nie odniesie większego sukcesu).

Precyzja, którą uzyskujemy, jest trudna, ale moim zdaniem warto ją praktykować.
Post by Maciej Sobczak
Post by g***@gmail.com
To co pokazałem w swoim artykule to po prostu idea, którą najwygodniej wyrazić w Lispie.
Konsekwentnie się nie zgadzam, z racji tego, że w LISPie w ogóle mało co się wygodnie wyraża. Zagnieżdżone pary? Rekurencja? Daj spokój.
Spróbuj przełożyć konstrukcję Byrda i Friedmana na język Wolframa.
Sam z chęcią zobaczę, jaki będzie efekt.
Post by Maciej Sobczak
Post by g***@gmail.com
Post by Maciej Sobczak
Sam artykuł oczywiście, jak zwykle, zniechęca do LISPa.
Powiedz coś więcej na ten temat. W jaki sposób zniechęca?
"Aren't all those closing parentheses beautiful?"
"The heavily parenthesized syntax of LISP may not be particularly readable."
Raczej bym powiedział, że "oddaje sprawiedliwość".
Lisp nie jest doskonałą notacją, ale to pewnie dlatego, że nie ma czegoś takiego, jak "doskonała notacja". Za to do meta-programowania jest najlepszą notacją, jaką znam.
Post by Maciej Sobczak
Post by g***@gmail.com
Nie rozumiem. Jakiego ograniczenia na liczbę elementów?
Wykład o LISPie zawsze kładzie nacisk na to, że albo mam jeden obiekt albo parę. I że jak chcę czegoś więcej, to jest to jakaś rzeźba z par. To nie jest ograniczenie? A potem się okazuje, że zmiana N-tego elementu wymaga rekurencji. Oczywiście, można to wszystko ukryć pod przystępnymi funkcjami bibliotecznymi, ale po co przykrywać problem, którego można po prostu nie mieć?
Nadal nie rozumiem. Jaka rzeźba z par? Jak chcesz tworzyć listę elementów a, b, c, to piszesz po prostu (list a b c) albo '(a b c).
LISP daje też potężny operator "quasiquote", który pozwala na budowanie złożonych struktur w efektywny sposób.
Post by Maciej Sobczak
Post by g***@gmail.com
A co jeśli owa wartość Nothing miałaby zostać przekazana jako argument do funkcji?
Na to też są sposoby, bo w takich specjalnych przypadkach można sterować dokładnym czasem ewaluacji. Niemniej, pytanie jest zasadne, ale zawsze można też odpowiedzieć, że można udawać, że takiego ficzeru w ogóle nie ma (tak jak go nie ma w innych językach), wtedy też nie powstaje problem z przekazywaniem Nothing jako parametr.
No, dla mnie to od początku brzmiało jak ficzer, którego lepiej udawać, że nie ma.
Post by Maciej Sobczak
Post by g***@gmail.com
W kilku miejscach - tam, gdzie poziom zagnieżdżeń przesłaniał istotę rzeczy - użyłem notacji Haskella.
Rozumiem. Czyli do programowania w LISPie potrzeby jest Haskell, żeby przekazać czytelnikowi o co chodzi w LISPowym kodzie.
Właśnie takie efekty mam na myśli.
Ale co w tym złego? Większość odpowiedzi i tak jest w języku angielskim.
Składnia Haskella ma swoją wartość, tak jak składnia Lispa.
(do wartości składni Wolframa nie jestem przekonany)
Post by Maciej Sobczak
Post by g***@gmail.com
Post by Maciej Sobczak
Inna rzecz - czy konstrukcja if musi być podstawową w LISPie?
To o co pytasz to absolutne podstawy lambda-rachunku.
https://www.cl.cam.ac.uk/teaching/Lectures/funprog-jrh-1996/all.pdf
rozdział 3
OK, czyli nie musi.
Ale żeby prawda i fałsz musiały wtedy być funkcjami? Daj spokój.
Proszę, oto spokój.
Post by Maciej Sobczak
Post by g***@gmail.com
Inna rzecz - czy pattern matching musi być podstawą w Wolframie?
Tak działa ewaluacja w Wolframie (to się nazywa "term rewriting": https://en.wikipedia.org/wiki/Rewriting). To podstawowy mechanizm, i tak dobrze udaje inne mechanizmy, że większość ludzi o nim zapomina, sądząc, że to jest po prostu "normalny wieloparadygmatowy język programowania".
Czyli musi.
Maciej Sobczak
2019-08-02 08:32:20 UTC
Permalink
Post by g***@gmail.com
Spróbuj przełożyć konstrukcję Byrda i Friedmana na język Wolframa.
Sam z chęcią zobaczę, jaki będzie efekt.
Normalnie mi się nie chce, mam inne zainteresowania.
Ale gdybym miał jakoś wesprzeć swój argument, to tutaj jest jakaś tabelka:

https://blog.wolfram.com/2012/11/14/code-length-measured-in-14-languages/

Z jakiejś statystyki wyszło, że programy w CommonLisp (to chyba najbliższy przykład do tej dyskusji) są ~6 razy dłuższe, niż w Wolframie. Nie wiem, czy ta statystyka rozciąga się też na Twoje przykłady, ale nie widzę powodu, żeby nie.
Post by g***@gmail.com
Lisp nie jest doskonałą notacją, ale to pewnie dlatego, że nie ma czegoś takiego, jak "doskonała notacja". Za to do meta-programowania jest najlepszą notacją, jaką znam.
A dlaczego akurat do meta-programowania jest najlepsza?
Post by g***@gmail.com
Nadal nie rozumiem. Jaka rzeźba z par? Jak chcesz tworzyć listę elementów a, b, c, to piszesz po prostu (list a b c) albo '(a b c).
Ładnie i wygodnie. To jak np. zamienić miejscami elementy ostatni z przedostatnim?

[Nothing]
Post by g***@gmail.com
No, dla mnie to od początku brzmiało jak ficzer, którego lepiej udawać, że nie ma.
Dlaczego? Bardzo fajny. Zwłaszcza jak się go zwraca z funkcji wywołanej w jakiejś pętli. Nie muszę wtedy usuwać "pustych" elementów w dodatkowym kroku.
Właśnie dlatego moja funkcja "only" była krótsza (i czytelniejsza) od Twojej w LISPie. Stąd się biorą potem takie tabelki, jak ta z linku powyżej.
Post by g***@gmail.com
Post by Maciej Sobczak
Rozumiem. Czyli do programowania w LISPie potrzeby jest Haskell
Ale co w tym złego?
Zależy, jakie masz cele w życiu. Język, który nie pozwala skupić się na problemie, nie pomaga.
Post by g***@gmail.com
(do wartości składni Wolframa nie jestem przekonany)
To ciekawe, bo mój znajomy mówi, że Wolfram mu się nie podoba, bo jest za bardzo LISPowaty. :-)
I ja się z nim zgadzam, że Wolfram jest LISPowaty. Tylko że on jest LISPowaty tylko w takim stopniu, w jakim jest to użyteczne.
Post by g***@gmail.com
Post by Maciej Sobczak
Post by g***@gmail.com
Inna rzecz - czy pattern matching musi być podstawą w Wolframie?
Czyli musi.
Ale co w tym złego?
--
Maciej Sobczak * http://www.inspirel.com
g***@gmail.com
2019-08-02 12:10:13 UTC
Permalink
Post by Maciej Sobczak
Post by g***@gmail.com
Spróbuj przełożyć konstrukcję Byrda i Friedmana na język Wolframa.
Sam z chęcią zobaczę, jaki będzie efekt.
Normalnie mi się nie chce, mam inne zainteresowania.
https://blog.wolfram.com/2012/11/14/code-length-measured-in-14-languages/
Z jakiejś statystyki wyszło, że programy w CommonLisp (to chyba najbliższy przykład do tej dyskusji) są ~6 razy dłuższe, niż w Wolframie. Nie wiem, czy ta statystyka rozciąga się też na Twoje przykłady, ale nie widzę powodu, żeby nie.
Czasem w radiu słyszę reklamy, że producent leku przeprowadził niezależne badania, z których wynika, że ich produkt jest najlepszy. Nie przekonują mnie, tak samo jak powyższe statystyki (zresztą wiadomo, jak to jest ze statystykami).

Trochę też rozczarowuje brak APLa w ich rankingu - pewnie wyszłoby jeszcze krócej, niż Mathematica, i by się musieli tłumaczyć.

W każdym razie "krócej" nie zawsze znaczy "lepiej". Kiedyś przekomarzałem się na ten temat z Jonem Harropem. Zadanie polegało na tym, żeby napisać program przekształcający program używający rekurencji do takiego, który używa Y-kombinatora. O jego rozwiązaniu faktycznie można powiedzieć, że było krótsze, ale było też zdecydowanie mniej czytelne.

Archiwa dyskusji (wraz z rozwiązaniem w Mathematice) można sobie poczytać tutaj:
https://www.quora.com/Why-is-Haskell-not-homoiconic/answer/Jon-Harrop-2/comment/31109325
natomiast moje roziązanie w Schemie (wraz z nieco bardziej szczegółowym wyjaśnieniem) można znaleźć tu:
https://github.com/panicz/master-thesis/blob/master/chapters/B.tex
Post by Maciej Sobczak
Post by g***@gmail.com
Lisp nie jest doskonałą notacją, ale to pewnie dlatego, że nie ma czegoś takiego, jak "doskonała notacja". Za to do meta-programowania jest najlepszą notacją, jaką znam.
A dlaczego akurat do meta-programowania jest najlepsza?
Chyba dlatego, że ma najmniejszą możliwą liczbę reguł, dzięki czemu składnia jest jednocześnie formatem serializacji (i to lżejszym od np. JSONa)
Post by Maciej Sobczak
Post by g***@gmail.com
Nadal nie rozumiem. Jaka rzeźba z par? Jak chcesz tworzyć listę elementów a, b, c, to piszesz po prostu (list a b c) albo '(a b c).
Ładnie i wygodnie. To jak np. zamienić miejscami elementy ostatni z przedostatnim?
No np. tak (z pattern-matcherem Shinna/Wrighta):

(let (((abc ... y z) some-list))
Post by Maciej Sobczak
[Nothing]
Post by g***@gmail.com
No, dla mnie to od początku brzmiało jak ficzer, którego lepiej udawać, że nie ma.
Dlaczego? Bardzo fajny. Zwłaszcza jak się go zwraca z funkcji wywołanej w jakiejś pętli. Nie muszę wtedy usuwać "pustych" elementów w dodatkowym kroku.
Właśnie dlatego moja funkcja "only" była krótsza (i czytelniejsza) od Twojej w LISPie. Stąd się biorą potem takie tabelki, jak ta z linku powyżej.
Nie powiedziałbym, żeby była czytelniejsza.
Na pewno do zrozumienia wymagała
- znajomości funkcji "map"
- wiedzy o osobliwym zachowaniu wartości "Nothing"

Łatwo jest zdefiniować "only" przy pomocy "append-map" (czy flatMap, czy concatMap, jak zwał tak zwał)

(define (only satisfying? elements)
(append-map (lambda (element)
(if (satisfying? element)
`(,element)
'()))
elements))

Wygląda prawie tak samo, jak Twoja, tylko nie trzeba wymyślać "specjalnych elementów" o "magicznych właściwościach" i "niejasnym statusie ontycznym".
Post by Maciej Sobczak
Post by g***@gmail.com
Post by Maciej Sobczak
Rozumiem. Czyli do programowania w LISPie potrzeby jest Haskell
Ale co w tym złego?
Zależy, jakie masz cele w życiu. Język, który nie pozwala skupić się na problemie, nie pomaga.
No w omawianym przypadku cel miałem raczej jasny: zaprezentowanie idei "uruchamiania ewaluatora wstecz".
Ale inna okoliczność, przy której składnia Lispa była nieodzowna, to np. system Boyera-Moore'a do dowodzenia twierdzeń o programach.
Post by Maciej Sobczak
Post by g***@gmail.com
(do wartości składni Wolframa nie jestem przekonany)
To ciekawe, bo mój znajomy mówi, że Wolfram mu się nie podoba, bo jest za bardzo LISPowaty. :-)
I ja się z nim zgadzam, że Wolfram jest LISPowaty. Tylko że on jest LISPowaty tylko w takim stopniu, w jakim jest to użyteczne.
Najwidoczniej wynika to stąd, że różne rzeczy są dla nas ważne.
Najwidoczniej dla mnie prostota jest ważniejsza od wygody (którą Ty tutaj nazywasz "użytecznością"), a dla Ciebie na odwrót.
Dla mnie prostota jest wartością dlatego, że te różne przygodne udogodnienia, które Wolfram dodaje do składni Lispa, z punktu widzenia meta-programowania wcale nie są udogodnieniami, tylko wręcz przeciwnie.

Każdy początkujący programista Lispa z łatwością doda sobie do niego różne udogodnienia składniowe, a jeśli będzie miał nieco więcej uporu, może zaimplementuje nawet pełną składnię Mathematiki w czytniku Lispa.

A później dostrzeże, że tego rodzaju "udogodnienia" stwarzają barierę między nim a resztą świata, bo składnia Lispa jest dostatecznie dobra (a jeśli korzysta się z wyspecjalizowanych narzędzi, jest nawet dużo lepsza), i jego wysiłki tylko wprowadzają chaos komunikacyjny.

Zaprawieni programiści Lispa nazywają ten proces "rytuałem przejścia".

Być może sytuacja z Mathematiką ma się nieco inaczej, bo ona ma już wokół siebie stosunkowo dużą społeczność.
Post by Maciej Sobczak
Post by g***@gmail.com
Post by Maciej Sobczak
Post by g***@gmail.com
Inna rzecz - czy pattern matching musi być podstawą w Wolframie?
Czyli musi.
Ale co w tym złego?
To samo, co w tym, że w danym języku nie da się zdefiniować swojego własnego "if"-a. Moim zdaniem absolutnie nic, ale to Ty rozpocząłeś ten wątek, więc powiedz: co w tym złego?
AK
2019-08-03 04:52:38 UTC
Permalink
Post by g***@gmail.com
Post by Maciej Sobczak
Ładnie i wygodnie. To jak np. zamienić miejscami elementy ostatni z przedostatnim?
(let (((abc ... y z) some-list))
O ja pieprnicze.. No rzeczywiscie "prosto"...

AK
g***@gmail.com
2019-08-03 07:55:37 UTC
Permalink
Post by AK
Post by g***@gmail.com
(let (((abc ... y z) some-list))
O ja pieprnicze.. No rzeczywiscie "prosto"...
Dla ignoranta nawet zwykłe dodawanie będzie wyglądało jak czarna magia.

Jeżeli uważasz, że umiesz prościej, to pokaż, a jeśli nie, to lepiej zachowaj takie światłe uwagi dla siebie.
AK
2019-08-07 22:44:30 UTC
Permalink
Post by g***@gmail.com
Post by AK
Post by g***@gmail.com
(let (((abc ... y z) some-list))
O ja pieprnicze.. No rzeczywiscie "prosto"...
Dla ignoranta nawet zwykłe dodawanie będzie wyglądało jak czarna magia.
Jeżeli uważasz, że umiesz prościej, to pokaż, a jeśli nie, to lepiej zachowaj
takie światłe uwagi dla siebie.
vec[-2], vec[-1] = vec[-1], vec[-2]

Tak sie to robi w _normalnym_ jezyku programowania, a nie jakies szmuje
buje z kompletnie nieczytelnym pattern matchingiem do tak prostackiej
wrecz operacji.

AK
Maciej Sobczak
2019-08-08 07:06:59 UTC
Permalink
Post by AK
vec[-2], vec[-1] = vec[-1], vec[-2]
Tak sie to robi w _normalnym_ jezyku programowania
W Wolframie jest nieco dłużej:

{vec[[-2]], vec[[-1]]} = {vec[[-1]], vec[[-2]]}

ale idea jest zachowana. Tak czy inaczej chodzi o fundament: lista musi być strukturą liniową z dostępem swobodnym a nie jakąś rekurencyjną matrioszką.

Niektóre języki odróżniają listy od tablic pod względem tego swobodnego dostępu, ale to jest rozróżnienie niskopoziomowe, przydatne powiedzmy w C/C++ lub w Adzie, ale kompletnie nieużyteczne w takich językach jak Python czy Wolfram.
--
Maciej Sobczak * http://www.inspirel.com
AK
2019-08-08 15:44:16 UTC
Permalink
Post by Maciej Sobczak
Post by AK
vec[-2], vec[-1] = vec[-1], vec[-2]
Tak sie to robi w _normalnym_ jezyku programowania
{vec[[-2]], vec[[-1]]} = {vec[[-1]], vec[[-2]]}
Dopuszczalnie. Nie ma o co kopii kruszyc (choc Wolframa nie lubie
bo zbyt Lispowaty i malo obiektowy - ale dobrze - j.w. - ze nie
"dogmatycznie" Lispowaty). Jest czytelne.
Post by Maciej Sobczak
ale idea jest zachowana. Tak czy inaczej chodzi o fundament: lista musi być strukturą liniową z dostępem swobodnym a nie jakąś rekurencyjną matrioszką.
Janiej/trafniej juz nie mozna :)
Post by Maciej Sobczak
Niektóre języki odróżniają listy od tablic pod względem tego swobodnego dostępu, ale to jest rozróżnienie niskopoziomowe, przydatne powiedzmy w C/C++ lub w Adzie, ale kompletnie nieużyteczne w takich językach jak Python czy Wolfram.
No niekoniecznie. Tzn "metodycznie" masz racje, ale wydajnosciowo
juz mniej. W Pythonie istnieje standardowa struktura typu tablice
- array() - o okreslonym i i stalym (w przeciwienstwie do list) -
typie danych, czyli zdecydowanie wydajniejsza ok (linked)list,
Oczywiscie obluga obu jest taka sama/bardzo podobna.

PS: Nalezy tez wspomniec o numpy arays.

AK
Maciej Sobczak
2019-08-08 20:04:47 UTC
Permalink
Post by AK
No niekoniecznie. Tzn "metodycznie" masz racje, ale wydajnosciowo
juz mniej. W Pythonie istnieje standardowa struktura typu tablice
- array() - o okreslonym i i stalym (w przeciwienstwie do list) -
typie danych, czyli zdecydowanie wydajniejsza ok (linked)list,
Oczywiscie obluga obu jest taka sama/bardzo podobna.
OK. Dla porównania, Wolfram oferuje tablice przeznaczone do pracy z typami numerycznymi:

https://reference.wolfram.com/language/ref/NumericArray.html

oraz ByteArray.
Służą do optymalizacji czasu obliczeń, zajętości pamięci (są zawsze spakowane) i do komunikacji z modułami napisanymi w C. Te tablice to naprawdę tablice, takie jak w C, żadnych dekoracji. Ale zestaw dostępnych typów jest z góry ograniczony.

To są jednak niskopoziomowe narzędzia, chociaż ich interfejs jest taki sam jak normalnej listy.

W Wolframie chodzi jednak o coś szerszego - lista to nie tylko {a,b,c}. Wszystko ma wewnętrznie taką samą postać, więc skoro {a,b,c} to w rzeczywistości List[a,b,c], to podobnie np. a+b+c to w rzeczywistości Plus[a,b,c]. I taki Plus ma te same mechanizmy dostępu co List, bo z punktu widzenia indeksowania to jest taka sama struktura danych. Czyli np.:

{a, b, c}[[2]]

b

(a + b + c)[[2]]

b

whatever[a, b, c][[2]]

b

Ciekawostka - indeksowanie tych struktur jest od 1, natomiast 0 jest indeksem specjalnym, który oznacza "głowę" całej konstrukcji:

{a, b, c}[[0]]

List

(a + b + c)[[0]]

Plus

whatever[a, b, c][[0]]

whatever

Wszystko działa tak samo i to jest ta "nieortodoksyjna LISPowatość" Wolframa, która ułatwia metaprogramowanie i przetwarzanie symboliczne. Nie ma natomiast żadnych gwarancji co do wewnętrznej implementacji tych struktur. Czy to są tablice, czy listy z dodatkowym indeksem czy jeszcze jakieś inne hashmapy - nie wiemy.
--
Maciej Sobczak * http://www.inspirel.com
Maciej Sobczak
2019-08-03 19:51:11 UTC
Permalink
Post by g***@gmail.com
Czasem w radiu słyszę reklamy, że producent leku przeprowadził niezależne badania,
Ale ten producent wziął dane z niezależnego serwisu (Rosetta Code). Ty też możesz te dane stamtąd wziąć.
Post by g***@gmail.com
Trochę też rozczarowuje brak APLa w ich rankingu
http://rosettacode.org/wiki/Category:Programming_Languages

Ja myślę, że tabelka by nie była czytelna, gdyby wszystkie języki tam uwzględnić.
Post by g***@gmail.com
pewnie wyszłoby jeszcze krócej, niż Mathematica, i by się musieli tłumaczyć.
Gorzej. W tej dyskusji to LISP wyglądałby jeszcze biedniej.
Post by g***@gmail.com
W każdym razie "krócej" nie zawsze znaczy "lepiej".
To prawda.
Post by g***@gmail.com
Post by Maciej Sobczak
A dlaczego akurat do meta-programowania jest najlepsza?
Chyba dlatego, że ma najmniejszą możliwą liczbę reguł, dzięki czemu składnia jest jednocześnie formatem serializacji (i to lżejszym od np. JSONa)
Dokładnie to samo można napisać o Wolframie (to jest ta "LISPowatość"). Przykładowo, cały notebook, cokolwiek by nie miał, zapisany na dysku jest jednym legalnym wyrażeniem.

[Nothing]
Post by g***@gmail.com
Na pewno do zrozumienia wymagała
- znajomości funkcji "map"
Bo akurat chciałem, żeby przykład był w stylu funkcjonalnym. Nie musiał być i nie musiało tam być funkcji map.
Post by g***@gmail.com
- wiedzy o osobliwym zachowaniu wartości "Nothing"
Bo właśnie to chciałem zaprezentować. Da się też bez tej wiedzy, czyli gorzej. Da się nawet tak samo źle, jak w Twoim przykładzie. Wolfram to bardzo uniwersalny język, może nawet udawać gorsze języki. :-)
Post by g***@gmail.com
Łatwo jest zdefiniować "only" przy pomocy "append-map" (czy flatMap, czy concatMap, jak zwał tak zwał)
(define (only satisfying? elements)
(append-map (lambda (element)
(if (satisfying? element)
`(,element)
'()))
elements))
Wygląda prawie tak samo, jak Twoja, tylko nie trzeba wymyślać "specjalnych elementów" o "magicznych właściwościach" i "niejasnym statusie ontycznym".
No jak nie. Ja tam widzę pustą listę gdy warunek nie jest spełniony. Skąd mam wiedzieć, że pusta lista jest ignorowana przez append-map? Przecież mogła być też dodana do wyniku.
A gdybym jednak chciał dodać pustą listę do wyniku?

W Wolframie pusta lista i Nothing to dwie różne sprawy.
Przykładowo:

only[condition_, list_] := Map[
Function[x,
If[condition[x], x, {}] (* tutaj jest {} zamiast Nothing *)
],
list
]

only[EvenQ, {1, 2, 3, 4, 5, 6, 7}]

{{}, 2, {}, 4, {}, 6, {}}

Jest różnica, prawda? Jak tą różnicę uzyskać w Twoim przykładzie?
Post by g***@gmail.com
Najwidoczniej dla mnie prostota jest ważniejsza od wygody (którą Ty tutaj nazywasz "użytecznością"), a dla Ciebie na odwrót.
Zgodziłbym się, gdyby Twoje przykłady były proste. Ale nie są.

[...]
Post by g***@gmail.com
Zaprawieni programiści Lispa nazywają ten proces "rytuałem przejścia".
Rozumiem. Wspominałeś już to określenie, ale wcześniej nie zrozumiałem. Czyli "rytuał przejścia" to sytuacja, kiedy ktoś bez sukcesu próbuje usprawnić język i ostatecznie rezygnuje z tego, wracając do języka bez usprawnień.

A jest jakaś fajna nazwa na sytuację, kiedy ktoś bez sukcesu próbuje usprawnić język i ostatecznie rezygnuje z tego i zmienia język na lepszy?
Nie wiem - rytuał wyjścia? odejścia? rozejścia?
Musi być jakaś fajna nazwa.
Post by g***@gmail.com
Być może sytuacja z Mathematiką ma się nieco inaczej, bo ona ma już wokół siebie stosunkowo dużą społeczność.
To pewnie ludzie po rytuale wyjścia z LISPa. :-D

W porównaniu do poprzednich postów, w których próbowałeś wykazać, że nikt z tego nie korzysta, zauważam pozytywną zmianę.
--
Maciej Sobczak * http://www.inspirel.com
g***@gmail.com
2019-08-03 22:37:43 UTC
Permalink
Post by Maciej Sobczak
Post by g***@gmail.com
Czasem w radiu słyszę reklamy, że producent leku przeprowadził niezależne badania,
Ale ten producent wziął dane z niezależnego serwisu (Rosetta Code). Ty też możesz te dane stamtąd wziąć.
Nawet zerknąłem z ciekawości.
Tak konkretniej to zerknąłem tutaj:
https://rosettacode.org/wiki/Levenshtein_distance

Rozwiązanie w Mathematice wyglądało tak:

EditDistance["kitten","sitting"]
->3
EditDistance["rosettacode","raisethysword"]
->8

Dla porównania rozwiązanie w Haskellu:

levenshtein :: Eq a => [a] -> [a] -> Int
levenshtein s1 s2 = last $ foldl transform [0 .. length s1] s2
where
transform ns@(n:ns1) c = scanl calc (n + 1) $ zip3 s1 ns ns1
where
calc z (c1, x, y) = minimum [y + 1, z + 1, x + fromEnum (c1 /= c)]

main :: IO ()
main = print (levenshtein "kitten" "sitting")


Czyli autorzy "rozwiązania" w Mathematice nie dostarczyli implementacji odległości Levenshteina, tylko skorzystali z wbudowanej. Wygląda zatem na to, że nawet nie zrozumieli reguł zabawy.
Przy takiej interpretacji rzeczywiście trudno się dziwić, że w Mathematice wychodzą najkrótsze implementacje.
Post by Maciej Sobczak
Post by g***@gmail.com
- wiedzy o osobliwym zachowaniu wartości "Nothing"
Bo właśnie to chciałem zaprezentować. Da się też bez tej wiedzy, czyli gorzej. Da się nawet tak samo źle, jak w Twoim przykładzie. Wolfram to bardzo uniwersalny język, może nawet udawać gorsze języki. :-)
Post by g***@gmail.com
Łatwo jest zdefiniować "only" przy pomocy "append-map" (czy flatMap, czy concatMap, jak zwał tak zwał)
(define (only satisfying? elements)
(append-map (lambda (element)
(if (satisfying? element)
`(,element)
'()))
elements))
Wygląda prawie tak samo, jak Twoja, tylko nie trzeba wymyślać "specjalnych elementów" o "magicznych właściwościach" i "niejasnym statusie ontycznym".
No jak nie. Ja tam widzę pustą listę gdy warunek nie jest spełniony. Skąd mam wiedzieć, że pusta lista jest ignorowana przez append-map? Przecież mogła być też dodana do wyniku.
A gdybym jednak chciał dodać pustą listę do wyniku?
To zamiast '() napisałbyś '(())
Post by Maciej Sobczak
Post by g***@gmail.com
Najwidoczniej dla mnie prostota jest ważniejsza od wygody (którą Ty tutaj nazywasz "użytecznością"), a dla Ciebie na odwrót.
Zgodziłbym się, gdyby Twoje przykłady były proste. Ale nie są.
Nie do końca wiem, które przykłady masz na myśli.
Post by Maciej Sobczak
[...]
Post by g***@gmail.com
Zaprawieni programiści Lispa nazywają ten proces "rytuałem przejścia".
Rozumiem. Wspominałeś już to określenie, ale wcześniej nie zrozumiałem. Czyli "rytuał przejścia" to sytuacja, kiedy ktoś bez sukcesu próbuje usprawnić język i ostatecznie rezygnuje z tego, wracając do języka bez usprawnień.
Raczej: próbuje usprawnić język, ale w międzyczasie odnajduje perspektywę, w której okazuje się, że pozorne usprawnienia wcale nic nie usprawniają. Że zmiana kształtu koła nie sprawia, że koło staje się lepszym kołem. Że tym, co było przeszkodą, nie były niedoróbki języka, tylko nawyki programisty.
Post by Maciej Sobczak
A jest jakaś fajna nazwa na sytuację, kiedy ktoś bez sukcesu próbuje usprawnić język i ostatecznie rezygnuje z tego i zmienia język na lepszy?
Zauważyłem, że często (w naszych różnych rozmowach, nie tylko teraz) posługujesz się takimi określeniami, jak "lepszy" czy "gorszy", tak jakby one same w sobie coś znaczyły.
Być może ma sens mówienie o tym, że coś jest lepsze dla jakiegoś danego celu niż coś innego, albo że jest lepsze względem jakiegoś kryterium czy jakiejś miary, ale nie wydaje mi się, żeby można było w ogóle powiedzieć, że dany język jest w jakimś absolutnym sensie lepszy od jakiegoś innego języka.
Post by Maciej Sobczak
Nie wiem - rytuał wyjścia? odejścia? rozejścia?
Musi być jakaś fajna nazwa.
Może "sytuacja utknięcia"?
Albo "nieprzejście rytuału przejścia"?
Post by Maciej Sobczak
Post by g***@gmail.com
Być może sytuacja z Mathematiką ma się nieco inaczej, bo ona ma już wokół siebie stosunkowo dużą społeczność.
To pewnie ludzie po rytuale wyjścia z LISPa. :-D
Nie wiem jacy to ludzie. Pytanie jest rzeczywiście ciekawe, ale mi brak narzędzi, żeby to ocenić. (Nie ukrywam jednak, że zdziwiłbym się, gdyby się okazało, że jakiś znaczący odsetek użytkowników Mathematiki miał wcześniej głębszy kontakt z Lispem)
Post by Maciej Sobczak
W porównaniu do poprzednich postów, w których próbowałeś wykazać, że nikt z tego nie korzysta, zauważam pozytywną zmianę.
Kiedy ja niby próbowałem coś takiego wykazać?
Maciej Sobczak
2019-08-04 20:57:08 UTC
Permalink
Post by g***@gmail.com
Nawet zerknąłem z ciekawości.
https://rosettacode.org/wiki/Levenshtein_distance
[...]
Post by g***@gmail.com
Czyli autorzy "rozwiązania" w Mathematice nie dostarczyli implementacji odległości Levenshteina, tylko skorzystali z wbudowanej. Wygląda zatem na to, że nawet nie zrozumieli reguł zabawy.
Niekoniecznie. Bo jeśli reguły zabawy były takie, żeby nie używać istniejących ficzerów, tylko biczować się na jak najniższym poziomie, to akurat pokazana przez Ciebie wersja w Haskellu też tego nie spełnia. foldl, scanl, zip3, minimum, print, itd. - naprawdę, autorzy nie zrozumieli reguł, powinni to wszystko napisać od zera.

Zaletą Wolframa jest właśnie te 5000+ funkcji, które od ręki coś robią. A ponieważ Wolfram jest LISPowaty, to nie da się wyraźnie oddzielić funkcji "podstawowych" od "bibliotecznych", bo wszystkie mają takie same prawa i nie ma żadnej niezbędnej.
Post by g***@gmail.com
Przy takiej interpretacji rzeczywiście trudno się dziwić, że w Mathematice wychodzą najkrótsze implementacje.
Problem w tym, że przy innej interpretacji mogłoby się okazać, że w wielu językach w ogóle nie dałoby się wielu rzeczy napisać, bo większość języków bez swojej biblioteki standardowej nie potrafi zrobić nawet Hello World.
Więc skoro reguły są takie, że bierzemy język *razem* z jego biblioteką standardową, to niestety w Wolframie ten konkretny przykładowy problem rozwiązuje się jednym wywołaniem odpowiedniej funkcji.

To trochę jakbyś chciał wymyślić takie reguły gry w piłkę, żeby Lewandowski nie mógł strzelić gola i żebyś wtedy mógł z nim wygrać. Sorry, ale przy normalnych, uczciwych regułach, Lewandowski wygrywa.

(nie żebym się znał na piłce i kto tam teraz rulez, ale mam nadzieję, że analogia jest zrozumiała)
Post by g***@gmail.com
Post by Maciej Sobczak
A gdybym jednak chciał dodać pustą listę do wyniku?
To zamiast '() napisałbyś '(())
Ale czad. Prawie zaczynam pamiętać te wszystkie specjalne szczególiki. Bo sorry, ale nadal tutaj jest specjalne traktowanie listy.
Post by g***@gmail.com
(Nie ukrywam jednak, że zdziwiłbym się, gdyby się okazało, że jakiś znaczący odsetek użytkowników Mathematiki miał wcześniej głębszy kontakt z Lispem)
Bardzo nieudolnie ukrywasz swoje poczucie wyższości nad resztą świata.

Otóż Wolfram sam twierdzi, że:

https://www.wolfram.com/language/faq/

"LISP and APL were two early influences"

https://blog.stephenwolfram.com/2013/06/there-was-a-time-before-mathematica/

"I had a pretty broad knowledge of other computer languages of the time, both the “ordinary” ALGOL-like procedural ones, and ones like LISP and APL."

I większy wywód tutaj, z wczesnej dokumentacji:

https://reference.wolfram.com/legacy/v1/contents/4.2.7.pdf

Przypuszczam, że takie doświadczenia dotyczą również jakiejś części użytkowników. Ile jest takich przypadków - nie wiem, ale biorąc pod uwagę, że w środowisku uczelnianym LISP jest silnie reprezentowany i wiele narzędzi związanych z matematyką było swego czasu napisanych w LISPie, to spodziewam się, że świadomość LISPa wśród użytkowników Wolframa jest co najmniej zauważalna.
--
Maciej Sobczak
g***@gmail.com
2019-08-05 10:44:59 UTC
Permalink
Post by Maciej Sobczak
Post by g***@gmail.com
Nawet zerknąłem z ciekawości.
https://rosettacode.org/wiki/Levenshtein_distance
[...]
Post by g***@gmail.com
Czyli autorzy "rozwiązania" w Mathematice nie dostarczyli implementacji odległości Levenshteina, tylko skorzystali z wbudowanej. Wygląda zatem na to, że nawet nie zrozumieli reguł zabawy.
Niekoniecznie. Bo jeśli reguły zabawy były takie, żeby nie używać istniejących ficzerów, tylko biczować się na jak najniższym poziomie, to akurat pokazana przez Ciebie wersja w Haskellu też tego nie spełnia. foldl, scanl, zip3, minimum, print, itd. - naprawdę, autorzy nie zrozumieli reguł, powinni to wszystko napisać od zera.
O ile mogę się zgodzić, że problem demarkacji nie jest w tym przypadku łatwy, o tyle nie zgodzę się z radykalnym wnioskiem.
Rozwiązanie Haskellowe, chociaż korzysta z funkcji wbudowanych, daje jednak możliwość zozumienia tego, co się dzieje pod spodem. Rozwiązanie w Mathematice takiej możliwości nie daje.
Prosta sprawa - zmodyfikuj rozwiązanie w Mathematice tak, żeby koszt zamiany elementu wynosił 2 a nie 1.
Post by Maciej Sobczak
Zaletą Wolframa jest właśnie te 5000+ funkcji, które od ręki coś robią. A ponieważ Wolfram jest LISPowaty, to nie da się wyraźnie oddzielić funkcji "podstawowych" od "bibliotecznych", bo wszystkie mają takie same prawa i nie ma żadnej niezbędnej.
To też jest interesujące: czy algorytm Levenshteina napisany w Mathematice będzie działał równie szybko jak ten wbudowany?
Czy może ten wbudowany został zaimplementowany w C?
Post by Maciej Sobczak
Post by g***@gmail.com
Przy takiej interpretacji rzeczywiście trudno się dziwić, że w Mathematice wychodzą najkrótsze implementacje.
Problem w tym, że przy innej interpretacji mogłoby się okazać, że w wielu językach w ogóle nie dałoby się wielu rzeczy napisać, bo większość języków bez swojej biblioteki standardowej nie potrafi zrobić nawet Hello World.
Więc skoro reguły są takie, że bierzemy język *razem* z jego biblioteką standardową, to niestety w Wolframie ten konkretny przykładowy problem rozwiązuje się jednym wywołaniem odpowiedniej funkcji.
W każdym razie zagadka "najkrótszego kodu" w Mathematice rozwiązana.
Każdy może wyciągnąć swoje wnioski.
Post by Maciej Sobczak
To trochę jakbyś chciał wymyślić takie reguły gry w piłkę, żeby Lewandowski nie mógł strzelić gola i żebyś wtedy mógł z nim wygrać. Sorry, ale przy normalnych, uczciwych regułach, Lewandowski wygrywa.
(nie żebym się znał na piłce i kto tam teraz rulez, ale mam nadzieję, że analogia jest zrozumiała)
Bardziej taka analogia, że wystawiamy w wyścigu biegaczy i motocyklistów.
Raczej nikogo nie zdziwi, że motocykliści dojadą szybciej na metę. Ale raczej nie wnioskowałbym stąd, że kondycja motocyklistów jest lepsza.
Post by Maciej Sobczak
Post by g***@gmail.com
Post by Maciej Sobczak
A gdybym jednak chciał dodać pustą listę do wyniku?
To zamiast '() napisałbyś '(())
Ale czad. Prawie zaczynam pamiętać te wszystkie specjalne szczególiki. Bo sorry, ale nadal tutaj jest specjalne traktowanie listy.
Tutaj nie ma żadnego specjalnego traktowania listy.
Funkcja "append-map" wymaga, żeby przekazana do niej funkcja zwracała listę. Funkcja tworzy listę wynikową sklejając ze sobą wyniki list cząstkowych, powstałych przez aplikację przekazanej funkcji do każdego elementu przekazanej listy.
Nie ma tu żadnych specjalnych szczególików.
Post by Maciej Sobczak
Post by g***@gmail.com
(Nie ukrywam jednak, że zdziwiłbym się, gdyby się okazało, że jakiś znaczący odsetek użytkowników Mathematiki miał wcześniej głębszy kontakt z Lispem)
Bardzo nieudolnie ukrywasz swoje poczucie wyższości nad resztą świata.
Zauważyłem, że niejednokrotnie w naszych dyskusjach zdarza Ci się wyjechać z jakimś dziwnym "ad personam" w moim kierunku. A to że próbuję szpanować, a to że jestem arogancki, a to że mam poczucie wyższości nad resztą świata.

Nie wiem, skąd się to u Ciebie bierze, ani czemu to ma służyć. Jeżeli masz jakieś pytania na temat mojej osobowości, to lepiej zapytaj, zamiast spekulować.

W tym kontekście, jeżeli miałbym mówić o "wyższości czegoś nad czymś", to bym powiedział, że wkład Johna McCarthy'ego w rozwój informatyki był moim zdaniem większy od wkładu Stephena Wolframa (który być może lepiej się potrafił sprzedać). Ale to tyle. Nie ma w tym przekonaniu absolutnie nic na mój temat.
Że Wolfram twierdzi, to mnie nie zaskakuje. Ale mówiłem o "znaczącym odsetku użytkowników", a nie o "odsetku znaczących użytkowników"
Post by Maciej Sobczak
Przypuszczam, że takie doświadczenia dotyczą również jakiejś części użytkowników. Ile jest takich przypadków - nie wiem, ale biorąc pod uwagę, że w środowisku uczelnianym LISP jest silnie reprezentowany i wiele narzędzi związanych z matematyką było swego czasu napisanych w LISPie, to spodziewam się, że świadomość LISPa wśród użytkowników Wolframa jest co najmniej zauważalna.
No właśnie. Ty się spodziewasz jednego, ja się spodziewam drugiego, i pewnie żaden z nas nigdy się na ten temat nie dowie niczego.
Roman Tyczka
2019-08-05 12:35:31 UTC
Permalink
Post by g***@gmail.com
Post by Maciej Sobczak
Post by g***@gmail.com
(Nie ukrywam jednak, że zdziwiłbym się, gdyby się okazało, że jakiś znaczący odsetek użytkowników Mathematiki miał wcześniej głębszy kontakt z Lispem)
Bardzo nieudolnie ukrywasz swoje poczucie wyższości nad resztą świata.
Zauważyłem, że niejednokrotnie w naszych dyskusjach zdarza Ci się wyjechać z jakimś dziwnym "ad personam" w moim kierunku. A to że próbuję szpanować, a to że jestem arogancki, a to że mam poczucie wyższości nad resztą świata.
Nie wiem, skąd się to u Ciebie bierze, ani czemu to ma służyć. Jeżeli masz jakieś pytania na temat mojej osobowości, to lepiej zapytaj, zamiast spekulować.
Raz spytałem, o ile pomnę to odpowiedzi nie było. Spytam jeszcze raz, dość
na temat, skąd ksywa "panicz"?
--
pozdrawiam
Roman Tyczka
g***@gmail.com
2019-08-05 12:58:49 UTC
Permalink
Post by Roman Tyczka
Raz spytałem, o ile pomnę to odpowiedzi nie było. Spytam jeszcze raz, dość
na temat, skąd ksywa "panicz"?
Kiedyś kolega mnie tak przezwał, i mi zostało.
(Dlaczego tak przezwał, tego nie wyjaśnił)
Kontekst historyczny swego czasu szerzej opisałem tutaj:
https://www.quora.com/What-is-something-you-wish-you-knew-when-you-first-started-functional-programming/answer/Panicz-Godek
Maciej Sobczak
2019-08-05 20:29:33 UTC
Permalink
Post by g***@gmail.com
Rozwiązanie Haskellowe, chociaż korzysta z funkcji wbudowanych, daje jednak możliwość zozumienia tego, co się dzieje pod spodem.
Słuszna uwaga. Ale Mathematica ma inne cele. To nie jest narzędzie dla ludzi, którzy chcą wiedzieć, co się dzieje, tylko raczej co się stanie. Omawialiśmy to już w okolicy open-source. Przy użyciu funkcji EditDistance Mathematica daje odpowiedź na pytanie, jaka jest odległość między wektorami w jakiejś tam mierze.
Post by g***@gmail.com
Prosta sprawa - zmodyfikuj rozwiązanie w Mathematice tak, żeby koszt zamiany elementu wynosił 2 a nie 1.
Pytanie jest fair i odpowiedź (również fair) jest taka: sam sobie policz. Możesz w Wolframie. Zaletą Wolframa jest to, że ma 5000+ gotowych odpowiedzi; nie jest jego wadą to, że nie wszystkie (nieskończoność!) odpowiedzi są gotowe - bo w ostatecznym porównaniu i tak jest lepiej, niż w językach, gdzie wszystko trzeba wyklepać ręcznie.
Post by g***@gmail.com
To też jest interesujące: czy algorytm Levenshteina napisany w Mathematice będzie działał równie szybko jak ten wbudowany?
Czy może ten wbudowany został zaimplementowany w C?
Dobre pytanie. Nie wiemy. Co więcej, nawet gdybyśmy się dowiedzieli, to w kolejnej wersji produktu może być inaczej. I nawet nie chodzi o język implementacji, ale również o takie sprawy jak automatyczne wykorzystanie dostępnej równoległości albo specjalnego sprzętu obecnego w systemie. Również w tym sensie Mathematica jest narzędziem wysokopoziomowym.
Post by g***@gmail.com
W każdym razie zagadka "najkrótszego kodu" w Mathematice rozwiązana.
Każdy może wyciągnąć swoje wnioski.
Tak. Wniosek jest taki, że statystycznie w Mathematice trzeba napisać najmniej kodu. To jest odpowiedź na zupełnie praktyczne pytanie kogoś, dla kogo komputer jest narzędziem pracy.
Post by g***@gmail.com
Bardziej taka analogia, że wystawiamy w wyścigu biegaczy i motocyklistów.
Raczej nikogo nie zdziwi, że motocykliści dojadą szybciej na metę. Ale raczej nie wnioskowałbym stąd, że kondycja motocyklistów jest lepsza.
Ale osoba zamawiająca pizzę ma gdzieś kondycję gościa, który z dumą przynosi wystygniętego kapcia, i to jeszcze jak już wszyscy goście sobie poszli.
Post by g***@gmail.com
Funkcja "append-map" wymaga, żeby przekazana do niej funkcja zwracała listę.
I w ten sposób zaprzeczasz swoim wcześniejszym pretensjom, że żeby coś tam zrozumieć w Wolframie, to trzeba znać działanie jego funkcji a może nawet trzeba przeczytać dokumentację. Z nazwy "append-map" nie wynika, że oczekuje list. Mapowanie ogólnie, zgodnie z nazwą, mapuje elementy. A tu proszę, xyz-map oczekuje listy.
Post by g***@gmail.com
Jeżeli masz jakieś pytania na temat mojej osobowości, to lepiej zapytaj
Nie da się. W tym zakresie nikt nie potrafi się sam zdiagnozować, muszę więc polegać na swoich (subiektywnych) odczuciach.
Post by g***@gmail.com
W tym kontekście, jeżeli miałbym mówić o "wyższości czegoś nad czymś", to bym powiedział, że wkład Johna McCarthy'ego w rozwój informatyki był moim zdaniem większy od wkładu Stephena Wolframa
Ależ nikt nie twierdzi inaczej. Ba, nawet Wolfram nie twierdzi, że ma jakikolwiek wkład w rozwój informatyki, on się raczej eksponował w innych obszarach. Natomiast to, że w celu ułatwienia sobie pracy w tych innych obszarach napisał program, który potem równolegle rozwinał się jako użyteczny produkt, jest niewątpliwie osiągnięciem, zarówno inżynierskim, jak i biznesowym.
--
Maciej Sobczak * http://www.inspirel.com
Maciej Sobczak
2019-08-06 08:55:03 UTC
Permalink
Post by Maciej Sobczak
Post by g***@gmail.com
Prosta sprawa - zmodyfikuj rozwiązanie w Mathematice tak, żeby koszt zamiany elementu wynosił 2 a nie 1.
Pytanie jest fair i odpowiedź (również fair) jest taka: sam sobie policz.
OK, żeby nie było, że jestem nieuprzejmy, i dla własnej zabawy, zrobiłem mały research w tej sprawie.
Jest taka fajna funkcja:

https://reference.wolfram.com/language/ref/SequenceAlignment.html

Ta funkcja rozpisuje różnice między sekwencjami, z czego można wyciągnąć poszczególne operacje (usunięcie, wstawienie, zamiana). Jeżeli dobrze zrozumiałem ćwiczenie, to rozwiązeniem może być takie coś:

myDistance[s1_, s2_] := Total[
Min[#] + Max[#] & /@
Cases[SequenceAlignment[s1, s2], a_List :> StringLength /@ a]
]

Pozwoliłem sobie użyć skróconych (idiomatycznych) zapisów na podstawowe operacje mapowania i lambdy - skoro w innych językach są śmieszne znaczki, to ja też skorzystam.

Wyrażenie Min+Max załatwia podwójne zliczenie zamian w porównaniu do wstawień/usunięć. Pełne wyrażenie dla dowolnych wag to:

replacementCost*Min[#] + deletionCost*(Max[#] - Min[#])

gdzie # to anonimowa para {del, ins}, gdzie del to ilość znaków do usunięcia a ins to ilość znaków do wstawienia; jeśli obie są niezerowe, to znaczy, że jest zastąpienie, więc np. para {3,5} oznacza, że są 3 znaki do zastąpienia i 2 do usunięcia/wstawienia. Wszystkie takie wartości są sumowane.
Czy to jest prawidłowy sposób liczenia - nie wiem, ale tak to zrozumiałem.

Czyli nadal nie wyszło jakoś dramatycznie dużo tego kodu, prawda?

Nadal jednak szukałbym gotowych implementacji tutaj (choćby po to, żeby skorzystać z optymalizacji, które ktoś zrobił za mnie):

https://reference.wolfram.com/language/guide/DistanceAndSimilarityMeasures.html

I właśnie na tym polega użyteczność tego produktu.
--
Maciej Sobczak * http://www.inspirel.com
g***@gmail.com
2019-08-06 20:57:57 UTC
Permalink
Post by Maciej Sobczak
Post by g***@gmail.com
Jeżeli masz jakieś pytania na temat mojej osobowości, to lepiej zapytaj
Nie da się. W tym zakresie nikt nie potrafi się sam zdiagnozować, muszę więc polegać na swoich (subiektywnych) odczuciach.
Szczerze powiedziawszy, jeżeli idzie o poznawanie ludzi, to mamy cały arsenał środków o wiele lepszych niż swoje subiektywne odczucia. Zresztą nawet to, w jaki sposób chcemy kategoryzować ludzi, czy wręcz sam fakt, że w ogóle chcemy ich kategoryzować, w większym stopniu świadczy o naszym własnym "kosmosie wewnętrznym", niż o tych osobach.

Serio. Jeżeli masz jakieś wątpliwości co do moich motywacji, to nic nie stoi na przeszkodzie, żeby przed wydaniem osądu zapytać. Z mojego doświadczenia odbiór tekstu potrafi się drastycznie różnić od intencji autora (kiedyś rozmawiałem z kolegą na czacie, i rozmowa poszła w takim kierunku, że prawie zaczęliśmy skakać sobie do gardeł. Kiedy porozmawialiśmy na żywo, okazało się, że jest luz)
Post by Maciej Sobczak
Post by g***@gmail.com
Post by g***@gmail.com
Prosta sprawa - zmodyfikuj rozwiązanie w Mathematice tak, żeby koszt zamiany elementu wynosił 2 a nie 1.
Pytanie jest fair i odpowiedź (również fair) jest taka: sam sobie policz.
OK, żeby nie było, że jestem nieuprzejmy, i dla własnej zabawy, zrobiłem mały research w tej sprawie.
https://reference.wolfram.com/language/ref/SequenceAlignment.html
myDistance[s1_, s2_] := Total[
]
Pozwoliłem sobie użyć skróconych (idiomatycznych) zapisów na podstawowe operacje mapowania i lambdy - skoro w innych językach są śmieszne znaczki, to ja też skorzystam.
No właśnie, i to mi się nie podoba. Widziałem w swoim życiu już takie wynalazki, i choć może przyspieszają nieznacznie samo pisanie, zdecydowanie utrudniają czytanie (i komplikują reguły użycia języka)

Kiedyś napisałem w Schemie takie rozwiązanie:


[define [edit-distance a b]
[match `[,a ,b]
[`[,a []]
[length a]] ; insert all from a
[`[[] ,b]
[length b]] ; insert all from b
[`[[,a0 . ,a*] [,b0 . ,b*]]
[min [+ [edit-distance a* b] 1] ; delete a0
[+ [edit-distance a b*] 1] ; delete b0
[+ [edit-distance a* b*] ; replace or leave alone
[if [equal? a0 b0] 0 2]]]]]]

Co prawda trzeba sobie przyswoić specjalne znaczenie przecinków i apostrofów, ale oprócz tego nie ma tu prawie nic oprócz nazywania i budowania/rozkładania struktur, a jedyne funkcje biblioteczne użyte w kodzie to min, length, + i equal?.

Struktura kodu blisko odzwierciedla matematyczną definicję z Wikipedii. Jak się zastosuje memoizację, to i szybkość działania tego programu nie jest tragiczna.

Pewnie w Mathematice można podobnie. Może nawet w jakimś sensie ładniej, bo nie trzeba tych przecinków i apostrofów. Ale też nie trzeba się w definicji odwoływać do tajemniczych funkcji, których zrozumienie samo w sobie jest wyzwaniem

[...]
Post by Maciej Sobczak
Czyli nadal nie wyszło jakoś dramatycznie dużo tego kodu, prawda?
Nie wyszło. Ale nadal wyszło mniej, niż powinno.
Post by Maciej Sobczak
https://reference.wolfram.com/language/guide/DistanceAndSimilarityMeasures.html
I właśnie na tym polega użyteczność tego produktu.
Jeżeli jest użyteczny, to super. Ale mam nadzieję, że teraz lepiej rozumiesz moją perspektywę i niechęć do środowisk programistycznych o zamkniętym kodzie.

Zresztą moim ideałem jest, żeby to kompilator szukał za mnie gotowych implementacji, żebym mógł korzystać z gotowych optymalizacji, które ktoś zrobił za mnie.
Maciej Sobczak
2019-08-07 07:39:51 UTC
Permalink
Post by g***@gmail.com
Post by Maciej Sobczak
myDistance[s1_, s2_] := Total[
]
Pozwoliłem sobie użyć skróconych (idiomatycznych) zapisów na podstawowe operacje mapowania i lambdy - skoro w innych językach są śmieszne znaczki, to ja też skorzystam.
No właśnie, i to mi się nie podoba.
Nie mam z tym problemu. Interpunkcja w Wolframie nie jest bardziej rozbudowana, niż powiedzmy w C++ a dla purystów (lub, co ważniejsze, automatycznych parserów i generatorów) wszystko ma dostępną tzw. pełną formę, zgodną ze schematem head[e1,e2,...].
Czyli idomatyczny zapis zawierający lambdę i mapowanie, np.:

#^2& /@ {1,2,3,4}

jest równoważny:

Map[Function[x, x^2], {1,2,3,4}]

ze spodziewanym wynikiem {1,4,9,16}.

To jest też zaletą Wolframa w stosunku do innych języków, które takich ustandaryzowanych zapisów nie umożliwiają i wymuszają swoją mniej lub bardziej cyrkową interpunkcję każdemu, kto tego języka używa. Ja w Wolframie mam wybór i stosuję skrócone zapisy tam i w takim zakresie, w jakim uznaję to za użyteczne. Ocena zależy też od tego, jaką żywotność ma mieć kod - projekt dłogofalowy i eksperymenty "na kolanie" to dwie różne sprawy (powyższy przykład to oczywiście ta druga kategoria). Fajnie, że Wolfram potrafi się dopasować do obu tych zastosowań.
Warto też zauważyć, że przy programowaniu w stylu funkcjonalnym wystarczy tylko kilka skrótów (lambda, mapy, transformacje), żeby spektakuralnie wpłynąć na ilość pisanego kodu. Te kilka skrótów to idiomy, które pojawiają się regularnie w dokumentacji i przykładach Wolframa, więc ich znajomość zdobywa się bardzo wcześnie. To nie jest poziom ekspercki.
Zobacz na pierwsze dwa przykłady tutaj:

https://reference.wolfram.com/language/ref/Map.html

Nie da się znać jednego i nie znać drugiego. To jest tak jak mała i wielka litery 'a' oraz 'A'.
Post by g***@gmail.com
Post by Maciej Sobczak
Czyli nadal nie wyszło jakoś dramatycznie dużo tego kodu, prawda?
Nie wyszło. Ale nadal wyszło mniej, niż powinno.
A kto decyduje, ile powinno? Mathematica jest narzędziem wysokopoziomowym.
Post by g***@gmail.com
Jeżeli jest użyteczny, to super. Ale mam nadzieję, że teraz lepiej rozumiesz moją perspektywę i niechęć do środowisk programistycznych o zamkniętym kodzie.
Wręcz przeciwnie. Rozumiem jeszcze gorzej, bo nie pokazałeś żadnej wady takiego rozwiązania. W Mathematice mam dostępne wszystkie opcje: mogę sięgnąć po gotową funkcję gdy chcę mieć od ręki gotowy wynik lub samemu napisać sobie algorytm, gdy chcę się wykazać rozumieniem tego jak działa. W tym drugim przypadku mogę stosować zapisy o różnym poziomie rygoru składniowego, żeby osiągnąć oczekiwane właściwości kodu. We wszystkich przypadkach jest albo krócej albo czytelniej (albo oba!), niż w dyskutowanych tutaj alternatywach.

Która z tych cech ma u mnie powodować "niechęć do środowisk programistycznych o zamkniętym kodzie"? Bo ja na skutek naszych dyskusji tylko się utwierdzam w przekonaniu, że Wolfram to bardzo dobra inwestycja.
Post by g***@gmail.com
Zresztą moim ideałem jest, żeby to kompilator szukał za mnie gotowych implementacji, żebym mógł korzystać z gotowych optymalizacji, które ktoś zrobił za mnie.
Ale przecież napisanie własnego algorytmu jest tu utrudnieniem, bo odwraca uwagę kompilatora od właściwego celu. Rozwiązaniem jest właśnie zestaw funkcji wysokopoziomowych - takich jak EditDistance czy inny SequenceAlignment. Tam są te optymalizacje, z których chcesz skorzystać.

Tzn. ja chcę. :-)
--
Maciej Sobczak * http://www.inspirel.com
Maciej Sobczak
2019-08-07 08:09:09 UTC
Permalink
Post by Maciej Sobczak
Map[Function[x, x^2], {1,2,3,4}]
Przepraszam, to jeszcze nie pokazuje istoty zagadnienia. Można jeszcze bardziej purystycznie (prościej?):

Map[Function[x, Power[x,2]], List[1,2,3,4]]

Czy ta wersja jest czytelniejsza? To zależy, kto czyta. Na pewno dla automatu jest najlepsza (i wewnętrznie tak właśnie widać wszystkie wyrażenia, więc metaprogramowanie i przetwarzanie symboliczne odbywa się na takim poziomie), ale człowiek potrafi korzystać ze skrótów. A jak widać jest ich w tym przykładzie nawet więcej, niż się na początku wydawało.
--
Maciej Sobczak * http://www.inspirel.com
g***@gmail.com
2019-08-07 09:10:45 UTC
Permalink
Post by Maciej Sobczak
Post by Maciej Sobczak
Map[Function[x, x^2], {1,2,3,4}]
Map[Function[x, Power[x,2]], List[1,2,3,4]]
Czy ta wersja jest czytelniejsza? To zależy, kto czyta.
To jest problem z pojęciem czytelności, że jest niedookreślone.
Ale ta wersja korzysta z mniejszej ilości reguł, które "czysty umysł" potencjalnego czytelnika musi sobie przyswoić, żeby móc ją zrozumieć.
I to akurat nie zależy od tego, kto czyta.
(No, chyba że ktoś by twierdził, że ludzie od razu się rodzą ze zdolnością do parsowania zapisu #^2& jako funkcji anonimowej. Ale np. moje osobiste doświadczenie falsyfikuje owo twierdzenie)

Być może użycie "list comprehensions" byłoby dla różnych osób czytelniejsze, tzn. coś jak

[x^2 | x <- {1,2,3,4}]
Post by Maciej Sobczak
Na pewno dla automatu jest najlepsza (i wewnętrznie tak właśnie widać wszystkie wyrażenia, więc metaprogramowanie i przetwarzanie symboliczne odbywa się na takim poziomie), ale człowiek potrafi korzystać ze skrótów.
Automat też potrafi korzystać ze skrótów. Automatowi naprawdę jest wszystko jedno. Automat zrobi wszystko, do czego go zaprogramujesz.

Moje pytanie jest takie, czy ta pierwsza wersja rzeczywiście ma jakąś znaczącą przewagę nad tą ostatnią - na tyle znaczącą, żeby uzasadniała komplikowanie reguł dotyczących notacji.

Moim zdaniem nie. Zdaniem Wolframa (i Twoim chyba także) najwidoczniej tak.

Piszesz powyżej, że "interpunkcja w Wolframie nie jest bardziej skomplikowana, niż w C++", ale ze znanych mi języków C++ ma niewątpliwie najbardziej skomplikowaną składnię (na tyle skomplikowaną, że sami jego twórcy sobie z nim nie radzą)
Maciej Sobczak
2019-08-07 12:02:28 UTC
Permalink
Post by g***@gmail.com
Post by Maciej Sobczak
Map[Function[x, Power[x,2]], List[1,2,3,4]]
Ale ta wersja korzysta z mniejszej ilości reguł, które "czysty umysł" potencjalnego czytelnika musi sobie przyswoić, żeby móc ją zrozumieć.
Bez przesady. W odróżnieniu od komputerów, człowiek nie musi "zarządzać" regułami, które zna. W szczególności znaczkologia, którą zna nawet ze szkoły podstawowej jest znacznie bardziej skomplikowana - dlatego dla większości ludzi zapis x^2 jest od razu czytelny, podczas gdy Power[x,2] budzi podejrzenia o jakiś podstęp, pomimo tego, że "korzysta z mniejszej ilości reguł". Podobnie jest z nawiasami, czy w ogóle z operatorami.
Dlatego też to:

a*x^2 + b*x + c

jest czytelniejsze, niż to:

Plus[c, Times[b, x], Times[a, Power[x, 2]]]

W pewnej optymalnej ilości skróty są więc czytelniejsze i naturalniejsze.
Post by g***@gmail.com
Być może użycie "list comprehensions" byłoby dla różnych osób czytelniejsze, tzn. coś jak
[x^2 | x <- {1,2,3,4}]
Żaden postęp w stosunku do zwykłego mapowania. To jest nadmiarowa notacja. Jeśli dla kogoś czytelna, fajnie, ale posługując się Twoim własnym argumentem, wymaga znajomości większej liczby reguł. I ma bardzo ograniczone zastosowania.
Post by g***@gmail.com
Automat też potrafi korzystać ze skrótów. Automatowi naprawdę jest wszystko jedno. Automat zrobi wszystko, do czego go zaprogramujesz.
Ale właśnie w przypadku automatu ja chcę, żeby był jak najprostszy. Bo wtedy spędze mniej czasu na jego programowaniu.
Post by g***@gmail.com
Moje pytanie jest takie, czy ta pierwsza wersja rzeczywiście ma jakąś znaczącą przewagę nad tą ostatnią - na tyle znaczącą, żeby uzasadniała komplikowanie reguł dotyczących notacji.
Tak. Jest prostsza dla tych, co znają znaczki. Dokładnie tak samo, jak z wielomianem kwadratowym ze szkoły z powyższego przykładu.
Post by g***@gmail.com
Moim zdaniem nie. Zdaniem Wolframa (i Twoim chyba także) najwidoczniej tak.
Błąd. Ja korzystam z *obu* wersji. Zależnie od tego, która jest w danym kontekście bardziej efektywna.
Znaczy - w każdym kontekście moja efektywność może być optymalna. :-)
Post by g***@gmail.com
Piszesz powyżej, że "interpunkcja w Wolframie nie jest bardziej skomplikowana, niż w C++", ale ze znanych mi języków C++ ma niewątpliwie najbardziej skomplikowaną składnię
Więc wiem, że będzie łatwiej. :-P
--
Maciej Sobczak * http://www.inspirel.com
g***@gmail.com
2019-08-07 14:43:35 UTC
Permalink
Post by Maciej Sobczak
Post by g***@gmail.com
Post by Maciej Sobczak
Map[Function[x, Power[x,2]], List[1,2,3,4]]
Ale ta wersja korzysta z mniejszej ilości reguł, które "czysty umysł" potencjalnego czytelnika musi sobie przyswoić, żeby móc ją zrozumieć.
Bez przesady. W odróżnieniu od komputerów, człowiek nie musi "zarządzać" regułami, które zna. W szczególności znaczkologia, którą zna nawet ze szkoły podstawowej jest znacznie bardziej skomplikowana - dlatego dla większości ludzi zapis x^2 jest od razu czytelny, podczas gdy Power[x,2] budzi podejrzenia o jakiś podstęp
Całkowicie się nie zgadzam.
Nigdy nie miałem w szkole wprowadzanego zapisu x^2.
W języku C ^ oznacza operację xor.
W Pythonie (i zdaje się że FORTRANie też) do potęgowania używa się operatora **.
Użycie symbolu ^ do wyrażenia potęgowania jest może uznane przez garstkę osób piszących w raczej niszowych językach.
Post by Maciej Sobczak
pomimo tego, że "korzysta z mniejszej ilości reguł". Podobnie jest z nawiasami, czy w ogóle z operatorami.
No właśnie. Ile godzin spędziliśmy w szkole, przyzwyczajając się do tej notacji?
Post by Maciej Sobczak
a*x^2 + b*x + c
Plus[c, Times[b, x], Times[a, Power[x, 2]]]
Tzn. chyba chciałeś powiedzieć, że Tobie wydaje się czytelniejsze, a nie "jest czytelniejsze", bo to ostatnie określenie nawet nie do końca wiadomo, co znaczy.
Post by Maciej Sobczak
W pewnej optymalnej ilości skróty są więc czytelniejsze i naturalniejsze.
Może raczej "w pewnych bardzo szczególnych okolicznościach".
W innych np. [a, b, c] będzie lepszą reprezentacją wielomianu, który powyżej zapisałeś.

Zresztą notacja matematyczna ma to do siebie, że jest zoptymalizowana względem dość specyficznego celu, mianowicie łatwości manipulacji formułami na papierze albo tablicy. Łatwiej jest zapisać "x", bo to tylko dwa ruchy ręką, niż, dajmy na to, "ilość" (czy cokolwiek chcemy wyrazić przy pomocy tej liczby)
Post by Maciej Sobczak
Post by g***@gmail.com
Być może użycie "list comprehensions" byłoby dla różnych osób czytelniejsze, tzn. coś jak
[x^2 | x <- {1,2,3,4}]
Żaden postęp w stosunku do zwykłego mapowania. To jest nadmiarowa notacja. Jeśli dla kogoś czytelna, fajnie, ale posługując się Twoim własnym argumentem, wymaga znajomości większej liczby reguł. I ma bardzo ograniczone zastosowania.
Tak samo jak /@ jest nadmiarową notacją.
List comprehensions mają jednak pewną przewagę nad map. Przy pomocy map nie napiszesz czegoś takiego:

[(x, y, z) | x <- [1 .. 100], y <- [1 .. 100], z <- [1 .. 100], x^2+y^2==z^2]
Post by Maciej Sobczak
Post by g***@gmail.com
Automat też potrafi korzystać ze skrótów. Automatowi naprawdę jest wszystko jedno. Automat zrobi wszystko, do czego go zaprogramujesz.
Ale właśnie w przypadku automatu ja chcę, żeby był jak najprostszy. Bo wtedy spędze mniej czasu na jego programowaniu.
A w przypadku człowieka dlaczego nie chcesz, żeby był jak najprostszy?
Post by Maciej Sobczak
Post by g***@gmail.com
Moje pytanie jest takie, czy ta pierwsza wersja rzeczywiście ma jakąś znaczącą przewagę nad tą ostatnią - na tyle znaczącą, żeby uzasadniała komplikowanie reguł dotyczących notacji.
Tak. Jest prostsza dla tych, co znają znaczki. Dokładnie tak samo, jak z wielomianem kwadratowym ze szkoły z powyższego przykładu.
Zrobiłem ankietę na Twitterze. Jak do tej pory zagłosowały 32 osoby.
Wygląda na to, że spośród nich zgadza się z Tobą dokładnie 0 osób.

https://twitter.com/PaniczGodek/status/1159029909672603648
Post by Maciej Sobczak
Post by g***@gmail.com
Moim zdaniem nie. Zdaniem Wolframa (i Twoim chyba także) najwidoczniej tak.
Błąd. Ja korzystam z *obu* wersji. Zależnie od tego, która jest w danym kontekście bardziej efektywna.
Znaczy - w każdym kontekście moja efektywność może być optymalna. :-)
Cały czas nie znam kontekstu, w którym ta druga notacja z haszami i małpami byłaby efektywniejsza.
Maciej Sobczak
2019-08-07 20:32:22 UTC
Permalink
Post by g***@gmail.com
Całkowicie się nie zgadzam.
Nigdy nie miałem w szkole wprowadzanego zapisu x^2.
No tak. Bo widzisz - w Mathematice ten zapis wygląda dokładnie tak jak w szkole. Natomiast po skopiowaniu go do grup dyskusyjnych jest x^2, bo w okienku, gdzie pisze tego posta, jest tylko taki font i nie ma superscriptu.
Post by g***@gmail.com
Użycie symbolu ^ do wyrażenia potęgowania jest może uznane przez garstkę osób piszących w raczej niszowych językach.
https://en.wikipedia.org/wiki/Exponentiation#In_programming_languages

MATLAB, Wolfram, R, Excel, Analytica, TeX, "most computer algebra systems".

"Garstka osób w niszowych językach", tak? Łomatko...
Sami użytkownicy Excela pewnie przykryliby liczebnie fanów wszystkich innych zapisów... Pozostali to ludzie zajmujący się profesjonalnie inżynierią i matematyką. Niech będzie, że to nieistotna garstka.
Post by g***@gmail.com
No właśnie. Ile godzin spędziliśmy w szkole, przyzwyczajając się do tej notacji?
Nie ważne ile. Ważne, że to była inwestycja, na której można bezpiecznie budować. Programiści nie startują od zera i zwykle są to ludzie z jakimś istniejącym już fundamentem intelektualnym. No chyba że robimy język dla kosmitów, jak w filmach sci-fi i zakładamy, że odbiorca nie kuma kompletnie nic.
Post by g***@gmail.com
[(x, y, z) | x <- [1 .. 100], y <- [1 .. 100], z <- [1 .. 100], x^2+y^2==z^2]
To, że w Twoim ulubionym języku nie napiszę, to jest Twój problem a nie mój. :-)

Map[
Function[triple,
Apply[Function[{x, y, z}, If[x^2 + y^2 == z^2, {x, y, z}, Nothing]], triple]
],
Tuples[Range[100], 3]
]

Nieco dłużej, ale Ty osiągnąłeś limit swojego zapisu a moja mapa nawet się nie rozgrzała.
W tym przypadku jednak nie użyłbym mapy, bo to jest system z ograniczeniami a nie transformacja i od mapy lepszy jest filtr:

Cases[Tuples[Range[100], 3], {x_, y_, z_} /; x^2 + y^2 == z^2]

Nawet działa >2x szybciej. I tak bym to zostawił.
Post by g***@gmail.com
A w przypadku człowieka dlaczego nie chcesz, żeby był jak najprostszy?
Bo polegam na tym, co człowiek już wie ze szkoły. To jest koszt, który już został poniesiony, więc mogę z niego za darmo skorzystać.
Post by g***@gmail.com
Zrobiłem ankietę na Twitterze. Jak do tej pory zagłosowały 32 osoby.
Wygląda na to, że spośród nich zgadza się z Tobą dokładnie 0 osób.
Ale znasz tą teorię psychologiczną, że otaczamy się ludźmi, którzy potwierdzają nasze poglądy (bo innych nie lubimy, więc nie chcemy ich mieć w kręgu znajomych)? Wiesz, co by wyszło, gdyby Wolfram taką ankietę zrobił na swoim profilu?
Post by g***@gmail.com
Cały czas nie znam kontekstu, w którym ta druga notacja z haszami i małpami byłaby efektywniejsza.
Problem w tym (podobnie jak w wielu poprzednich tematach), że nie da się ustawić obiektywnej granicy pomiędzy znaczkami rozsądnymi a nierozsądnymi. Od nawiasów, przez podstawowe operatory, po strzałki po hasze i małpy. Dla Ciebie małpa jest nieczytelna, dla kogoś innego nieczytelny będzie znak plusa.

Granica czytelności jest subiektywna i zależy od... kręgu znajomych.
--
Maciej Sobczak * http://www.inspirel.com
Borneq
2019-08-06 13:31:48 UTC
Permalink
Post by g***@gmail.com
Hej,
gdyby ktoś był zainteresowany, to ostatnio opublikowałem na Quorze nieco przydługawy artykuł (czy może raczej "małą książkę"?) objaśniający technikę Friedmana i Byrda "uruchamiania ewaluatora od tyłu".
https://www.quora.com/Can-you-explain-to-non-coders-the-most-impressive-code-youve-seen/answer/Panicz-Godek
W ogólności pytanie "jaki jest najbardziej imponujący kod, jaki widziałeś" wydaje mi się ciekawe, więc jeśli ktoś tu ma jakieś swoje obserwacje na ten temat, z chęcią bym się dowiedział.
Pozdrawiam
Daję namiar:
https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf

"Relational Programming in miniKanren:Techniques, Applications,
andImplementations"
g***@gmail.com
2019-08-06 13:45:59 UTC
Permalink
Post by Borneq
Post by g***@gmail.com
gdyby ktoś był zainteresowany, to ostatnio opublikowałem na Quorze nieco przydługawy artykuł (czy może raczej "małą książkę"?) objaśniający technikę Friedmana i Byrda "uruchamiania ewaluatora od tyłu".
https://www.quora.com/Can-you-explain-to-non-coders-the-most-impressive-code-youve-seen/answer/Panicz-Godek
W ogólności pytanie "jaki jest najbardziej imponujący kod, jaki widziałeś" wydaje mi się ciekawe, więc jeśli ktoś tu ma jakieś swoje obserwacje na ten temat, z chęcią bym się dowiedział.
Pozdrawiam
https://scholarworks.iu.edu/dspace/bitstream/handle/2022/8777/Byrd_indiana_0093A_10344.pdf
"Relational Programming in miniKanren:Techniques, Applications,
andImplementations"
Posiłkowałem się tym, zwłaszcza przy obsłudze więzów.
Inne źródło to artykuł Friedmanna i Hemanna o minimalistycznej wersji minikanrena zwanej "microkanren" (albo uKanren):

http://webyrd.net/scheme-2013/papers/HemannMuKanren2013.pdf

Ale jeśli ktoś ma za małą motywację do czytania, to jest też film warsztatowy:



Przyznam też, że pomocna była dla mnie lektura źródeł microkanrena w Haskellu (dzięki systemowi typów rozumiało mi się to dużo lepiej, niż implementację w Scheme):
https://gist.github.com/msullivan/4223fd47991acbe045ec

ale moja implementacja różni się na kilka istotnych sposobów od miniKanrena, bo mieliśmy inne priorytety - im zależało na przenośności i integrowalności ich języka w różnych środowiskach (i w pewnej mierze na wydajności), a mnie na czytelności języka i łatwości prezentacji
Borneq
2019-08-06 14:32:02 UTC
Permalink
Post by g***@gmail.com
https://gist.github.com/msullivan/4223fd47991acbe045ec
Co to znaczy microkanren w Haskellu?
Czy ten mały program to interpreter w Haskellu składni schemapodobnej
microkanrena czy też rozszerzenie Haskella i microkanren ma tu składnię
haskelopoodbną?
g***@gmail.com
2019-08-06 14:39:36 UTC
Permalink
Post by Borneq
Post by g***@gmail.com
https://gist.github.com/msullivan/4223fd47991acbe045ec
Co to znaczy microkanren w Haskellu?
Czy ten mały program to interpreter w Haskellu składni schemapodobnej
microkanrena czy też rozszerzenie Haskella i microkanren ma tu składnię
haskelopoodbną?
Tzn. ma składnię wywiedzioną z Haskella (nie tyle "Haskellopodobną", tylko taką, na jaką Haskell naturalnie pozwala swoimi konstruktorami typów i funkcji anonimowych)

na dole wklejonego powyżej linka jest kilka przykładów wyrażeń w Haskellowym microKanrenie.

MiniKanren jako taki nie ma swojej składni, jego składnia jest z założenia "pasożytnicza" na składni goszczącego języka.

Różne implementacje języków *Kanren można znaleźć tutaj:
http://minikanren.org/

Jak byś sobie chciał zobaczyć jak to wygląda np. w JavaScripcie, to tutaj masz przykłady:
https://github.com/tca/veneer/blob/master/mk_test.js
Borneq
2019-08-06 14:57:16 UTC
Permalink
Post by g***@gmail.com
MiniKanren jako taki nie ma swojej składni, jego składnia jest z założenia "pasożytnicza" na składni goszczącego języka.
http://minikanren.org/
To świetnie, widzę że nawet język nie musi być funkcyjny. Widzę Javę i
Rust (co prawda nie ma C++, ale to chyba z braku odśmiecania pamięci)
Najbardziej znam Javę, więc w wolnym czasie przyjrzę się:
https://github.com/nd/mk.java
i
https://github.com/heidisu/java8kanren
g***@gmail.com
2019-08-06 15:20:14 UTC
Permalink
Post by Borneq
Post by g***@gmail.com
MiniKanren jako taki nie ma swojej składni, jego składnia jest z założenia "pasożytnicza" na składni goszczącego języka.
http://minikanren.org/
To świetnie, widzę że nawet język nie musi być funkcyjny. Widzę Javę i
Rust (co prawda nie ma C++, ale to chyba z braku odśmiecania pamięci)
W Rust też chyba nie ma odśmiecania pamięci.
Podejrzewam, że odkąd w C++ są lambdy, powinno się w nim bez problemu dać zaimplementować jakiegoś miniKanrena (a w najgorszym razie można po prostu alokować pamięć i jej nie zwracać)
Borneq
2019-08-06 15:01:42 UTC
Permalink
Post by g***@gmail.com
https://github.com/tca/veneer/blob/master/mk_test.js
A tu widzę w przeglądarce
http://tca.github.io/veneer/examples/editor.html
ale składnia wydaje mi się że przypomina kanren w schemie a nie JavaScript
Loading...