Prototyp ciekawego i minimalistycznego języka programowania

0

Zajmowałem się trochę taką biblioteką (do podświetlania składni) i zrobiłem tutorial dla chomika. link Myślę, że niedługo będzie gotowy, jest tam już parę ważnych dla Chomika rzeczy. Gdyby ktoś chciał ten tutorial, żeby zrobić takie samo podświetlanie składni to proszę - link.

1

Jest nowa wersja chomika - 0.0.7. Chomik ma kilka opcji w command line (-p, -v, -m). -v (albo --version) wypisuje tylko wersję i wychodzi, -p (albo --program-report) kompiluje zadany program, ale nie wykonuje go, tylko wypisuje wewnętrzny raport programu i też wychodzi, a -m (albo --memory-report) kompiluje program, wykonuje go i wypisuje raport pamięci.

Dzisiaj dorzuciłem do niej support dla UTF-8. To nie działa dobrze pod Windowsami, bo tam jest zdaje się inne kodowanie, ale na Linuksie działa. No i na sandboxie (link). Na przykład jeśli wykonamy kod:

<create new output stringstream>;
let x=<the created stream index>;
#
# now let us tell the 'print' to write to this stream
#
let the print target stream index=<x>;
let the print end of line = value string "";
<print "今日は">;
let the print target stream index=value integer 0; # back to the standard output
let the print end of line = value string "\n";
#
let the read from stream max size=value integer 1; # we read 1 by 1 (UTF-8 characters!)

# now let us tell the 'read from stream "string"' to read from it:
let the read from stream source stream index=<x>;
<read from stream "string">; 
<print <the read from stream result "string">>;

... to chomik z tekstu "今日は" wytnie pierwszy znak (今), bo 'the read from stream max size' jest liczony w znakach, nie w bajtach. Nie ma typu char, bo go nie potrzeba. Są tylko stringi.

Oprócz tego dodałem mnożenie i dzielenie (tylko dla integerów), wynik z dzielenia jest float (tak naprawdę Chomik reprezentuje floaty za pomocą double). No i jeszcze takie ulepszenie, które powoduje, że można używać innych placeholderów w przypisaniu jakiejś zmiennej a innych w wywołaniu. Dopisałem kilka pozycji do tutoriala (link). Dorzuciłem też kilka testów (trzy ostatnie są do tego UTF-8).

Jest też skrypt w bashu "build_for_windows.sh" i dwie dodatkowe opcje w configure.ac. Można przy konfiguracji wyłączyć budowanie serwerów (--disable-chomik-servers) i włączyć build dla Windows (--enable-windows-build).

Acha - użyłem gprof i sprawdziłem, co jest najwolniejsze. Wyszło mi, że dla wbudowanych symboli niepotrzebnie buduję ich nazwy i sygnatury w runtimie (sygnatura to nazwa z wszystkimi placeholderami zmienionymi na wartości). No i wyrzuciłem to z runtime, chomik i sdl_chomik są teraz szybsze.

Myślałem nad tym kodowaniem - może dodam jakąś wbudowaną zmienną, która będzie chomikowi mówić czy to build na windows czy nie. Albo jakie jest docelowe kodowanie.

To tyle z nowości w Chomiku.

0

Nowy chomik (0.0.8) zawiera dwie ciekawe rzeczy.

Jedna to drobiazg, dostęp do zmiennej typu string o nazwie 'the chomik package version'. Od tej wersji począwszy jest predefiniowana taka zmienna, odpowiadająca PACKAGE_VERSION z config.h. Dodałem test (test21.chomik), w którym wypisuję tą zmienną:

#!/usr/local/bin/chomik

<print <the chomik package version>>;

Teraz ten test wypisuje 0.0.8. Z każdą kolejną wersją ta zmienna będzie oczywiście inicjowana aktualną wartością. Dzięki temu aplikacja może sprawdzić, czy chomik bądź sdl_chomik jest z odpowiedniej wersji.

Druga rzecz jest ciekawsza. Istnieje wbudowana rodzina zmiennych typu kod o nazwie zaczynającej się na 'get is defined'. Służy do sprawdzania, czy dana zmienna/rodzina zmiennych jest zdefiniowana w pamięci. Ustawia ona predefiniowaną zmienną 'the get is defined result' typu boolean. Np. dla zmiennej o nazwie 'a b c' można wywołać:

let the get is defined result = value boolean true;
<get is defined a b c>;
<print <the get is defined result>>; # jeśli wypisze true to znaczy, że 'a b c' istnieje w pamięci.

Ta zmienna zawierająca wynik (the get is defined result) powinna być zainicjowana przez użytkownika, bo dzięki temu możemy później użyć placeholderów. Np. aby sprawdzić, czy wszystkie zmienne z rodziny 'a (X:boolean) (Y:boolean)' istnieją w pamięci możemy wykonać kod:

let the get is defined result = value boolean true;
<get is defined a (X:boolean) (Y:boolean)>;
<print <the get is defined result>>; # jeśli wypisze true to znaczy, że 'a false false', 'a false true', 'a true false' i 'a true true' 
                                     # istnieją w pamięci.
3

Nie zrozum mnie źle ale ten kod czyta się równie przyjemnie jak asemblera.

0
hzmzp napisał(a):

Nie zrozum mnie źle ale ten kod czyta się równie przyjemnie jak asemblera.

Rozumiem. Czyli ciężko się to czyta? Sorry - można by rozbić to i okomentować, np. ostatni kod:


let the get is defined result = value boolean true;   # ustawiamy rezultat "get is defined" na true

<get is defined                         # sprawdzamy czy zdefiniowano ...
    a (X:boolean) (Y:boolean)           # ... a X Y dla wszystkich par (X,Y) z X,Y typu boolean
>;

<print                                  # wypisz
  <the get is defined result>           # wartość rezultatu "get is defined"
>;

W ostateczności można zrobić własny parser (byleby używał API z pliku src/parser_functions.cc) i wykombinować jakąś własną składnię. Może składnia jest istotnie mało przejrzysta. Myślałem o czymś takim:

{
X:boolean;
Y:boolean;
<get is defined                         # sprawdzamy czy zdefiniowano ...
    a X Y                               # ... a X Y dla wszystkich par (X,Y) z X,Y typu boolean
>;
}

Ale to wydawało mi się mniej eleganckie.

1

Może wyjaśnię dlaczego używam znaków <> aby pobrać wartość zmiennej. Dzięki temu zmienne mogą mieć nazwy wieloczłonowe, np.:

variable a b c:integer;

Poniższe wyrażenia w C++ są przykładami nazw zmiennych:

a[x][0]
a.b
*a

W Chomiku wszystkie one są składniowo tym samym, dla powyższego przykładu byłoby one odpowiednio:

<a <x> 0>
<a b>
<<a>>

Ponadto dzięki nawiasom trójkątnym mogę mieć takie np. konstrukcje jak chomikowa "instrukcja warunkowa":

variable a (B:boolean):code;
let a false = value code { <print "bye">; };
let a true = value code { <print "hello">; };

variable b:boolean;
let b=true;
<a <b>>;

zamiast:

if (b) { std::cout << "hello"; } else { std::cout << "bye"; }

Rozwijając powyższy przykład - mogę te nawiasy trójkątne kombinować z pętlami "implicite":

variable a (B:boolean):code;
let a false = value code { <print "bye">; };
let a true = value code { <print "hello">; };

<a (S:boolean)>; # to wypisze "bye" (wykona a false) i "hello" (wykona a true)

Myślę, że do czasów Chomika wszystkie języki imperatywne miały niepotrzebnie taką samą strukturę - niejako dziedziczoną z języka na język. Stos, instrukcje warunkowe, pętle itp. W Chomiku mogę sobie zrobić stos (będzie on oczywiście rodziną zmiennych), ale przeważnie takiej struktury nie potrzebuję. Chomik obywa się też bez instrukcji warunkowych i bez jawnych pętli.

W innym wątku (Gotrek - mój pierwszy większy projekt ...) piszę o grze w sdl_chomiku, która ma już prawie 1MB kodu i obywa się bez tych wszystkich cudów jakie ma np. C++ czy nawet Perl.

Edit. Podejście do kodu w Chomiku też jest zdrowsze. Mógłbym zrobić sobie operacje na kodzie, np. konkatenacje, bo kod jest trzymany w zwykłych zmiennych typu kod. W "normalnych" czyli niechomikowych językach kod jest jakby osobnym bytem - obok danych.

0

Cześć,
Chciałem podzielić się takim odkryciem z Chomika, które dopiero dzisiaj przyszło mi do głowy. Otóż można zdefiniować sobie enumeracje składające się z identyfikatorów (i nie tylko), które odpowiadają nazwom rzeczywiście istniejących zmiennych. W poniższym przykładzie taką enumeracją jest magic. W ten sposób w Chomiku można uzyskać efekt analogiczny do wskaźników.

type magic={a,b,c,d};
expand(1);

let a = value magic b;
let b = value magic c;
let c = value magic d;
let d = value magic a;

<print <(X:magic)> <<(X:magic)>> <<<(X:magic)>>> <<<<(X:magic)>>>>>;

Ten program wypisuje:

b c d a 
c d a b 
d a b c 
a b c d 

Placeholder (X:magic) spowoduje iterację po wszystkich wartościach typu magic, czyli a,b,c,d. Dla każdej takiej wartości, np. dla a, print wypisze co zawiera zmienna a, zmienna wskazywana przez zmienną a, zmienna wskazywana przez zmienną wskazywaną przez zmienną a itd.

Oczywiście można tą technikę kombinować ze zmiennymi różnych typów. Na przykład:

type magic={a,b,c,d};
expand(1);

let a = value integer 100;
let b = value float 3.14159;
let c = value string "hallo";
let d = value boolean false;

<print <(X:magic)>>;

Ten program wypisze wartości zmiennych a,b,c,d, które mają różne typy.

1
Paweł Biernacki napisał(a):

Cześć,
Chciałem podzielić się... W ten sposób w Chomiku można uzyskać efekt analogiczny do wskaźników.

Pytanie, czy wskaźnik akurat jest takim elementem języka/ów programowania, który jest największym (pozytywnym) marzeniem.
Dla mnie to oglądanie się za rozwiązaniem (może) najbardziej ilościowo masowym, ale jednym z słabszych jako koncepcja / wstecznym

ps. lubię design języków / kompilatorów, ale wolał bym generowanie nowych, nowoczesnych konceptów, również eksperymentalnych - nie każdy z nich się sprawdzi, nie każdy się ostoi w czasie, to inna sprawa.

Trzeba z żywymi naprzód iść,
Po życie sięgać nowe...
A nie w uwiędłych laurów liść
Z uporem stroić głowę.

0

Zapomniałem napisać, że chomikowe "wskaźniki" są oczywiście lepsze od wskaźników np. z C/C++. W gruncie rzeczy to zmienne typów wyliczeniowych (enumeracji). W tradycyjnych językach imperatywnych zmienne typów wyliczeniowych nie mają nic wspólnego ze wskaźnikami. Służą do reprezentowania wartości, na których właściwie nie ma żadnych operacji poza porównaniem (na równość). Z kolei wskaźniki muszą być wykorzystywane jako wskaźniki właśnie, czyli nie mają sensu jeśli nie dokonuje się ich dereferencji. Ale nie to jest najgorsze. Muszą na przykład wskazywać jednoznacznie na zmienną konkretnego typu. Nie mogą wskazywać na "część nazwy" zmiennej nieznanego typu.

W Chomiku jest inaczej.
Wartością enumeracji może być sekwencja bytów zwanych w Chomiku generic_name_items. Pojedynczym generic_name_item może być identyfikator, albo nawet literał dowolnego wbudowanego typu. Jednocześnie sekwencja generic_name_items może być nazwą zmiennej. Czyli to co jest wartością jednej zmiennej może być nazwą innej zmiennej, albo nawet fragmentem nazwy innej zmiennej. I tak dalej. Pojedyncza zmienna jest jakby wskaźnikiem na wartość pewnego typu. Zmienna wyliczeniowa może (choć nie musi) być wykorzystywana jako wskaźnik. Ponieważ nazwa zmiennej jest listą (sekwencją) generic_name_items, a listy można konstruować z innych list, to w Chomiku można wykorzystać technikę "dereferencji złożenia". Nie muszą przy tym wskazywać na wartość określonego z góry typu.

type epsilon = {a,b};
expand(1);
let a a = value integer 123;
let a b = value float 3.14159;
let b b = value string "hallo";
let b a = value boolean true;
<print <(X:epsilon) (Y:epsilon)>>;

Powyższy program wypisze po kolei wartości zmiennych, z których każda jest innego typu:

123 
true 
3.14159 
hallo 

Tej techniki język C po prostu nie oferuje. Chomikowa "pętla" iteruje po wszystkich elementach iloczynu kartezjańskiego {a,b} x {a,b} i konstruuje nazwy zmiennych, do których chcemy się odwołać.
Może nie mam pod ręką przykładu, dlaczego te "wskaźniko-enumeracje" są pożyteczne, ale już wiem, że są bardzo silne.

2

Nie chcę tu jakoś negować sensu twojego języka, ale tak porównując do innych, to tak - w Pythonie klucze słowników mogą być krotkami, czyli mogą zawierać kilka wartości naraz, więc powyższy kod można osiągnąć tak:

data = dict()
data[('a', 'a')] = 123
data[('a', 'b')] = 3.14159
data[('b', 'b')] = "hallo"
data[('b', 'a')] = True

for value in data.values(): 
	print(value)

co daje output:

123
3.14159
hallo
True

możemy też się odwoływać do pojedynczych wartości w słowniku:

print(data[('a', 'b')]) # 3.14159

Z kolei jeśli chciałbyś faktycznie iloczyn kartezjański w Pythonie, to jest funkcja product z modułu itertools i zamiast pętli po wszystkich wartościach słownika, możemy lecieć po wszystkich kombinacjach kluczy:

from itertools import product
# ... (kod powyżej ustawiający wartości w słowniku `data`
keys = ('a', 'b')
for key in product(keys, keys): 
	print(key, data[key])

output:

('a', 'a') 123
('a', 'b') 3.14159
('b', 'a') True
('b', 'b') hallo

(chociaż to by było trochę bez sensu w tym przypadku, żeby zakładać, że dany klucz jest w słowniku, ale jednak - da się).

I nawiasem mówiąc tej opcji tworzenia kluczy złożonych z kilku różnych wartości mi brakuje w JS i zdarzało mi się, że emulowałem to za pomocą sklejania kilku wartości w jeden string jako klucz.

Co do iloczynu kartezjańskiego w JS, trochę nie rozumiem problemu, to można osiągnąć zagnieżdżonymi pętlami for.

const keys = ['a', 'b'];
for (const k1 of keys) {
   for (const k2 of keys) {
       console.log(k1, k2);
   }
}

output:

a a
a b
b a
b b
0

Na githubie jest nowa wersja Chomika (0.1.0). Dorzuciłem nową, intrygującą funkcjonalność.link
W odróżnieniu od języków pozostałych zmienne w Chomiku mają nazwy składające się nie z pojedynczego identyfikatora, ale z listy tzw. name itemów, z których każdy może być identyfikatorem, ale może być też dowolnym literałem. To nie była do końca prawda - nie działało to dla literałów typu code. Teraz działa.

Dorzuciłem test (test23.chomik), którego fragment pozwolę sobie tutaj przytoczyć:

let the print separator = value string "";
let the print end of line = value string "";

variable abc (X:code) (Y:code):code;
let abc (X:code) (Y:code)=value code
{
    let x = value code [(X:code)];
    let y = value code [(Y:code)];
    <print "hello">;
    <x>;
    <print "bye">;
    <y>;
};

<abc {<print "alpha" (S:boolean)>;} {<print "beta" (S:boolean)>;}>;

W ten sposób można jakby przesyłać kod do wewnątrz innego kodu. Powyższy przykład wypisuje tekst:

helloalphafalsebyebetafalsehelloalphatruebyebetatrue

Działa to następująco: iterujemy po wszystkich wartościach S typu boolean. Są to false i true. Następnie wywołujemy:

<abc {<print "alpha" false>;} {<print "beta" false>;}>;
<abc {<print "alpha" true>;} {<print "beta" true>;}>;

Dla każdego z tych wywołań "wstrzykujemy" do 'abc (X:code) (Y:code)' różne wartości X i Y. Kod 'abc (X:code) (Y:code)' przypisze wartości placeholderów X i Y odpowiednio do zmiennych x i y, następnie wypisze "hello", wykona zmienną x, wypisze "bye" i wykona zmienną y.

W sumie wywołanie dla S=false wypisze helloalphafalsebyebetafalse,
a wywołanie dla S=true wypisze helloalphatruebyebetatrue.

3

Fajny projekt, dodawałeś do niego opcje JIT i AOT?
Czy to tylko engine, który interpretuje instrukcje?

Ogólnie przykłady, które podajesz są mega zagmatwane i trudne w analizie, powinieneś coś prostszego i bardziej użytecznego podać.

Powiedzmy jakiś problem jest biblioteka gym z grami, w której jest masa problemów.
Matematycy zaczynają od prostych funkcji, żeby je zoptymalizować,

Programista na pamięć też się nie uczy też musi zrozumieć ja bym dał jakiś prosty problem i jego rozwiązanie bo tak trochę nie wiadomo o co chodzi.
I też tą kompilację AoT jak nie masz bym dodał :>
Jak masz to przepraszam mój błąd.

0
GodOfCode. napisał(a):

Fajny projekt, dodawałeś do niego opcje JIT i AOT?
Czy to tylko engine, który interpretuje instrukcje?

Nie, nie ma kompilacji JIT ani AOT. To tylko interpreter. Ma mniej więcej rok, zacząłem go pisać na początku kwietnia 2022.

Ogólnie przykłady, które podajesz są mega zagmatwane i trudne w analizie, powinieneś coś prostszego i bardziej użytecznego podać.

Przepraszam. Może zerknij na https://www.perkun.org/chomik_tutorial.html, tam jest tutorial Chomika, staram się wyjaśnić jak co działa. Mam też dokument PDF, ale będę musiał jeszcze nad nim popracować.

Powiedzmy jakiś problem jest biblioteka gym z grami, w której jest masa problemów.
Matematycy zaczynają od prostych funkcji, żeby je zoptymalizować,

Chomik otwiera zupełnie nowe możliwości. Pisałem o tym już kilkakrotnie - na przykład rekurencyjne enumeracje z cyklicznymi zależnościami.

Programista na pamięć też się nie uczy też musi zrozumieć ja bym dał jakiś prosty problem i jego rozwiązanie bo tak trochę nie wiadomo o co chodzi.
I też tą kompilację AoT jak nie masz bym dodał :>
Jak masz to przepraszam mój błąd.

2
Paweł Biernacki napisał(a):

Na githubie jest nowa wersja Chomika (0.1.0). Dorzuciłem nową, intrygującą funkcjonalność.link
W odróżnieniu od języków pozostałych zmienne w Chomiku mają nazwy składające się nie z pojedynczego identyfikatora, ale z listy tzw. name itemów, z których każdy może być identyfikatorem, ale może być też dowolnym literałem. To nie była do końca prawda - nie działało to dla literałów typu code. Teraz działa.

brakuje mi w tym jakiegoś odniesienia do koncepcji z innych języków programowania. Na ile to, co robisz jest podobne, a na ile się różni od tego, co można znaleźć w innych językach. mają nazwy składające się nie z pojedynczego identyfikatora, ale z listy tzw. name itemów, z których każdy może być identyfikatorem, ale może być też dowolnym literałem. --> to mi przypomina jakąś mapę indeksowaną po kilku wartościach (np. w Pythonie słowniki mogą być indeksowane po krotkach(tuples), w JS można to emulować w inny sposób). I brakuje mi informacji, na ile twoje rozwiązanie jest podobne, na ile inne.

To by pomogło zrozumieć, bo "aaa, znam to podejście, widziałem to w innym języku".
ew. "aaa, to co innego niż w innym języku, ciekawe podejście, nie znałem!".

Poza tym:

zmienne w Chomiku mają nazwy składające się nie z pojedynczego identyfikatora, ale z listy tzw. name itemów,

Ten opis również kojarzy mi się z destructuringiem, co raczej jest błędnym tropem (w destructuringu zmiennych jak w JS można mieć kilka różnych zmiennych w jednej deklaracji po prostu https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment ), tym niemniej jeśli mi taki błędny(jak się domyślam) trop przyszedł na myśl, to możliwe, że komuś innemu też przyjdzie.

W ten sposób można jakby przesyłać kod do wewnątrz innego kodu.

Czy kod jest czymś podobnym, co funkcja albo domknięcie(closure) czy blok w innych językach?

0
LukeJL napisał(a):

brakuje mi w tym jakiegoś odniesienia do koncepcji z innych języków programowania. Na ile to, co robisz jest podobne, a na ile się różni od tego, co można znaleźć w innych językach. mają nazwy składające się nie z pojedynczego identyfikatora, ale z listy tzw. name itemów, z których każdy może być identyfikatorem, ale może być też dowolnym literałem. --> to mi przypomina jakąś mapę indeksowaną po kilku wartościach (np. w Pythonie słowniki mogą być indeksowane po krotkach(tuples), w JS można to emulować w inny sposób). I brakuje mi informacji, na ile twoje rozwiązanie jest podobne, na ile inne.>

Słuszne skojarzenie, rzeczywiście to jest mapa. We wszystkich znanych mi językach imperatywnych (poza Chomikiem) nazwa zmiennej jest identyfikatorem. W Chomiku nazwą może być dowolny ciąg identyfikatorów przemieszanych z literałami wbudowanych typów. Nawet pojedynczy literał może być nazwą zmiennej, ale to raczej dziwaczny przypadek.

Chomik różni się w bardzo wielu aspektach od np. C++. Spróbuję wymienić najważniejsze różnice:

  • w Chomiku nie ma żadnej instrukcji pętli - pętle są tworzone implicite, jako przypisania bądź wykonania kodu dla wszystkich elementów iloczynu kartezjańskiego pewnych zbiorów, determinowanych przez tzw. placeholdery
  • w Chomiku nie ma struktur danych, są tylko rodziny zmiennych, wszystkie zmienne są globalne
  • w Chomiku istnieje wbudowany typ code, można tworzyć zmienne tego typu i "wykonywać je"
  • w Chomiku nie ma instrukcji warunkowej, ale istnieje możliwość stworzenia przy pomocy rodziny zmiennych typu kod czegoś, co działa tak samo
  • w Chomiku są tzw. rekurencyjne typy wyliczeniowe z cyklicznymi zależnościami, bardzo ciekawa cecha
  • żeby dobrać się do wartości zmiennej w Chomiku należy użyć nawiasów trójkątnych <>, to tylko pozornie syntactic sugar, mogłyby to być oczywiście dowolne nawiasy, ale chodzi o to, że wyrażenie oznaczające "wartość zmiennej" może być kombinowane z placeholderami
  • Chomik jest językiem interpretowanym (na razie nie ma kompilatora Chomika)
  • nie ma stosu - można sobie stworzyć rodzinę danych, która działa jak stos, albo nawet kilka takich rodzin
  • nie ma koncepcji przekazywania parametrów do funkcji, można funkcjami sterować za pomocą zmiennych globalnych i/lub elementów nazwy będących placeholderami

Ten ostatni punkt chciałbym wyjaśnić:

variable a b (C:boolean) (D:boolean):code;
let a b (X:boolean) (Y:boolean)= value code 
{
  let my x = value boolean [(X:boolean)];
  let my y = value boolean [(Y:boolean)];
  <print <my x> "and" <my y> "is false">;
}; # tu się kończy pierwsze przypisanie

let a b true true = value code { <print "HELLO">; }; # tu się kończy drugie przypisanie

<a b (S:boolean) (T:boolean)>; # a tu jest wywołanie 

W powyższym kodzie po wykonaniu pierwszego przypisania rodzina zmiennych 'a b (X:boolean) (Y:boolean)' składa się z czterech zmiennych utworzonych według pewnego wzorca (zmienne 'my x' i 'my y' zależą od placeholderów odpowiednio X:boolean i Y:boolean). Iloczyn kartezjański boolean x boolean to zbiór par:

(false, false), (false,true), (true, false), (true, true)

Ma on jak widać cztery elementy.

W drugim przypisaniu nadpisujemy jedną z czterech zmiennych z tej rodziny, a mianowicie 'a b true true' przypisując jej kod, który od żadnych placeholderów nie zależy. W tym przypisaniu (drugim) w ogóle nie ma placeholderów, chociaż mogłyby być.

Wywołanie w powyższym przykładzie wypisze:

false and false is false 
true and false is false 
false and true is false 
HELLO 

Widać stąd, że za pomocą przypisań można dowolnie zmienić "wartość" zmiennej typu kod, a zatem związek między elementami nazwy, jakimi są placeholdery a tym, co faktycznie kod robi jest bardzo luźny.

To by pomogło zrozumieć, bo "aaa, znam to podejście, widziałem to w innym języku".
ew. "aaa, to co innego niż w innym języku, ciekawe podejście, nie znałem!".

Nie znam innego języka podobnego do Chomika.

Poza tym:

zmienne w Chomiku mają nazwy składające się nie z pojedynczego identyfikatora, ale z listy tzw. name itemów,

Ten opis również kojarzy mi się z destructuringiem, co raczej jest błędnym tropem (w destructuringu zmiennych jak w JS można mieć kilka różnych zmiennych w jednej deklaracji po prostu https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment ), tym niemniej jeśli mi taki błędny(jak się domyślam) trop przyszedł na myśl, to możliwe, że komuś innemu też przyjdzie.

To skojarzenie nie jest, jak sądzę, poprawne - w Chomiku są tylko rodziny zmiennych, które od biedy można by zinterpretować jako mapy krotek na jakieś wartości, ale nie ma w nim żadnych struktur danych.

W ten sposób można jakby przesyłać kod do wewnątrz innego kodu.

Czy kod jest czymś podobnym, co funkcja albo domknięcie(closure) czy blok w innych językach?

Tak. Kod jest tym samym co funkcja pozbawiona argumentów i nie zwracająca żadnej wartości (choć mogąca przypisywać wartości dowolnym zmiennym).

0

Cześć,
W Chomiku 0.1.0 jest problem - w parserze. Wykrzacza się przy dużej ilości statementów. Dodałem na githuba wersję 0.1.1, która ma YYMAXDEPTH ustawione na milion. Może kiedyś przepiszę parser, tak, żeby nie korzystać z bisona. Przez ten błąd przestałem pisać "gotreka", ale na www.perkun.org jest nowy projekt (fantasy_chomik_demo). Wykorzystałem w nim pewne doświadczenia z gotreka, np. do wygenerowania pewnych wartości typów wyliczeniowych wykorzystuję integery jako identyfikatory osób, miejsc, kluczy. Po skonfigurowaniu należy odpalić "make run" w tym projekcie.

Ciekawe w nim jest tłumaczenie wygenerowanych enumów na język naturalny (angielski). Poniżej kilka przykładów takich "tłumaczeń":

Akcja Tłumaczenie
askperson2whetherperson3canseeperson1istrue ask Gerrudir whether Gwaigilion can see me
askperson2whetherperson1hasthekeyopeningplace3isfalse ask Gerrudir whether I do not have the key opening Cintra
askperson3whetherperson1hasthekeyopeningplace3istrue ask Gerrudir whether I have the key opening Cintra
askperson2toattackperson1 ask Gerrudir to attack me
tellperson3thatperson2haskey1isfalse tell Gwaigilion that Gerrudir does not have the golden key

W katalogu "generated" jest kod wygenerowany automatycznie (przez programy umieszczone w katalogu "generators"). To są przypisania wartości z rodzin zmiennych wykorzystywanych do "parsowania" akcji. W Gotreku próbowałem to zrobić w czasie rzeczywistym, ale to jest zbyt wolne, jak się okazuje. Z kodem generowanym działa dużo lepiej. Nie musicie go generować u siebie (chyba, że zmienicie wartości w common/config.sdl_chomik), np. ilość osób, wtedy trzeba odpalić "make generated_code".

0

Mam prośbę - moglibyście zerknąć na https://www.perkun.org/chomik.html i powiedzieć mi czy ta strona jest OK, ewentualnie co poprawić.

Dzisiaj znalazłem memory leak w Chomiku (w parserze), i teraz śmiga. Napisałem już sporo kodu w tym języku (ściśle rzecz biorąc w SDL_Chomiku) i mogę powiedzieć, że pisze się fajnie. Pomyślałem, że dobrze byłoby zainteresować tym projektem jakiegoś korpoludka albo bogatego inwestora. Myślicie, że mam szanse? Przydałoby mi się kilka milionów dolarów, no, przynajmniej jeden. Ja sam z siebie jestem skromnym programistą, ale chciałem kupić synowi Lamborgini ;))))

1
Paweł Biernacki napisał(a):

Mam prośbę - moglibyście zerknąć na https://www.perkun.org/chomik.html i powiedzieć mi czy ta strona jest OK, ewentualnie co poprawić.

O, widzę, że dorobiłeś kolorowanie składni?
https://www.perkun.org/chomik_tutorial.html#assigning_a_simple_code_variable
No i dobrze, bo to dodaje powagi językowi.

Dzisiaj znalazłem memory leak w Chomiku (w parserze), i teraz śmiga. Napisałem już sporo kodu w tym języku (ściśle rzecz biorąc w SDL_Chomiku) i mogę powiedzieć, że pisze się fajnie. Pomyślałem, że dobrze byłoby zainteresować tym projektem jakiegoś korpoludka albo bogatego inwestora. Myślicie, że mam szanse?

Zapewne niewielkie, chociaż były już takie przypadki. Np. polski startup Enso(d. Luna) dostał 16,5 miliona dofinansowania. Tylko tam robią nie tylko język programowania, ale również wizualne środowisko do niego. https://techcrunch.com/2022/04/19/enso-emerges-from-stealth-to-help-enterprises-make-sense-of-their-data/

Eve - wirtualne środowisko programistyczne i język - dostali 2,3 miliony dolarów
https://techcrunch.com/2014/10/01/eve-raises-2-3m-to-rethink-programming
pobawili się kilka lat w robienie prototypów, a potem porzucili projekt
https://news.ycombinator.com/item?id=16227130

No ale też zwróć uwagę, że te rzeczy wyglądały dobrze i obiecywały dużo, to nie był po prostu język.
https://witheve.com/
https://enso.org/

Przydałoby mi się kilka milionów dolarów, no, przynajmniej jeden.

To znajdź zastosowanie komercyjne do tego języka albo takie, które łatwo będzie wytłumaczyć inwestorom - np. język do AI.

0

Szukam jakiegoś ciekawego zastosowania dla Chomika, które nie byłoby grą. I chodzi mi po głowie coś takiego:

Napisać w Chomiku "system ekspertowy", właściwie sam szkielet, który ulepszałby trochę OOP.
1, obiekt ma jedynie tożsamość (tak jak enum), obiekt nie jest zbiorem wartości atrybutów klasy
2. oprócz obiektów mamy fakty, które opisują relacje między nimi, fakty nie są obiektami
3. obiekt może być jednoznacznie zdefiniowany (przez fakty), ale nie istnieć, np. X < -5 i jednocześnie X > 5
4. obiekt może być jednoznacznie zdefiniowany i istnieć, ale nie być skonstruowanym
5. obiekt może być jednoznacznie zdefiniowany i istnieć, ale możemy nie dysponować kodem, który jest w stanie go skonstruować
6. możemy nawet dysponować dowodem, że kod konstruujący dany obiekt nie może istnieć, chociaż sam obiekt istnieje (coś jak twierdzenie o nierozstrzygalności)
7. skonstruować obiekt to znaczy zdefiniować i obliczyć pewną ilość atrybutów (np. wszystkie rozwiązania danego równania), atrybuty są takimi bytami jak obiekty, tj. również opisanymi przez fakty, ale jeśli są skonstruowane to mają wartość danego typu
8. "klasa" to tylko informacja, jakie atrybuty należy obliczyć, aby można było uznać obiekt za skonstruowany
9. konstrukcji można dokonać na podstawie relacji z obiektami zdefiniowanymi i istniejącymi, ale niekoniecznie skonstruowanymi

Innymi słowy zamiast "klasa"->"obiekt" u mnie byłoby:

"obiekt"->"zdefiniowany obiekt"->"jednoznacznie zdefiniowany obiekt"->"istniejący obiekt"->"konstruowalny obiekt"->"konstruowalny przez NAS (w skończonym czasie) obiekt"->"skonstruowany obiekt".

Zacząłem już pisać taki "system ekspertowy", najbardziej pomagają w Chomiku te rekurencyjne typy wyliczeniowe. Wiem oczywiście, że istnieją systemy algebraiczne, które są silniejsze niż wszystko co zdołam napisać (np. Maxima), ale one wszystkie są napisane w ciężkich, tj. niechomikowych językach, więc mam trochę przewagi.

Niestety oceniam szanse na to, że ktoś mi zapłaci za komercyjną licencję Chomika na bardzo mizerne. Chociaż większe od zera ;)))

1 użytkowników online, w tym zalogowanych: 0, gości: 1