Alqor — Bölmə 8: Modullar və Paketlər#


8.1 Modul anlayışı#

Hər .alq faylı bir moduldur. Modul adı fayl adından gəlir:

riyazi-alətlər.alq   →   modul adı: riyazi_alətlər
şəbəkə/http.alq      →   modul adı: şəbəkə.http

8.2 İxrac — ixrac et#

Standart olaraq hər şey gizlidir. Yalnız ixrac et ilə işarələnən üzvlər kənardan görünür.

Alqor
// riyazi.alq

ixrac et sabit Pİ = 3.14159265358979

ixrac et funksiya kvadrat(x: onluq) -> onluq
    qaytar x * x
son

ixrac et sinif Vektor
    ...
son

funksiya daxiliKöməkçi()          // ixrac olunmur — gizli
    ...
son

// Toplu ixrac
ixrac et {kvadrat, kub, kök}

// Standart ixrac (modulun əsas elementi)
ixrac et standart funksiya hesabla() ... son

// Yenidən ixrac
ixrac et {topla, çıx} riyazi.əsasdan
ixrac et * riyazi.həndəsədən

8.3 İdxal — gətir#

Bütöv modul#

Alqor
gətir riyaziyyat

yaz(riyaziyyat.Pİ)
yaz(riyaziyyat.kök(16))

Ləqəblə#

Alqor
gətir riyaziyyat kimi r

yaz(r.Pİ)

Seçmə idxal#

Alqor
gətir riyaziyyat.{Pİ, kök, qüvvət}

yaz(Pİ)
yaz(kök(16))

Ləqəbli seçmə idxal#

Alqor
gətir riyaziyyat.{kök kimi kvadratKök, Pİ kimi PI}

Hamısını idxal (tövsiyə olunmur)#

Alqor
gətir riyaziyyat.*

Niyə riyaziyyatdan deyil? Azərbaycan dilinin təbii forması riyaziyyatdan gətir {kök} olardı. Amma -dan şəkilçisi sözə yapışır və lekser üçün riyaziyyatdan bir identifikator tokenidir — şəkilçini ayırmaq mümkün deyil. Ayırmağa çalışsaq, meydan, qazan, vətən kimi adlı modullar sınar.

Ona görə seçmə idxal nöqtə-mötərizə sintaksisi ilə yazılır: gətir riyaziyyat.{kök}. Qısa, qeyri-ikimənalı, şəkilçisiz. Bu, dilin aqqlütinativ təbiətinin kompilyator dizaynına birbaşa təsir etdiyi yerlərdən biridir.

Standart idxal#

Alqor
gətir riyazi.standart kimi hesabla   // `ixrac et standart` elementi

Yerli fayldan#

Alqor
gətir "./köməkçilər.alq" kimi k
gətir "../ortaq/model.alq" kimi model
gətir "./alt_qovluq/" kimi alt    // qovluğun `indeks.alq` faylı

Paketdən#

Alqor
gətir veb                         // standart kitabxana
gətir @şirkət/analitika           // ad fəzalı paket
gətir tarix_alətləri              // alqorhub paketi

Python kitabxanasından#

Alqor
gətir python:numpy kimi np            // PyPI paketi (`alqor python qur numpy`)
gətir python:os.path                  // alt modul → `path` adı
gətir python:math.{sqrt, pi kimi PI}  // seçmə idxal

Ətraflı: § 8.14.

Şərti idxal#

Alqor
@əgərHədəf("veb")
gətir brauzer

@əgərHədəf("desktop")
gətir pəncərə

Dinamik idxal (asinxron)#

Alqor
asinxron funksiya yüklə()
    dəyişən modul = gözlə gətirDinamik("./ağır-modul.alq")
    modul.işlət()
son

8.4 Modul daxilində modul bloku#

Bir faylda bir neçə ad fəzası:

Alqor
// həndəsə.alq

ixrac et modul ikiÖlçülü
    ixrac et sinif Nöqtə
        xassə x: onluq
        xassə y: onluq
    son
son

ixrac et modul üçÖlçülü
    ixrac et sinif Nöqtə
        xassə x: onluq
        xassə y: onluq
        xassə z: onluq
    son
son
Alqor
gətir həndəsə

dəyişən a = yeni həndəsə.ikiÖlçülü.Nöqtə()
dəyişən b = yeni həndəsə.üçÖlçülü.Nöqtə()

8.5 Modulun ilkinləşdirilməsi#

Alqor
// verilənlər.alq

dəyişən _bağlantı: Bağlantı?

// Modul ilk dəfə idxal olunanda bir dəfə işləyir
başlanğıc
    _bağlantı = Bağlantı.aç(sistem.mühit("DB_URL"))
    jurnal.info("Verilənlər bazası bağlandı")
son

// Proqram bitəndə işləyir
bitiş
    _bağlantı?.bağla()
son

8.6 Dövri asılılıqlar#

Alqor dövri idxalı aşkarlayır və xəta verir (ALQ-M005):

✖ ALQ-M005  Dövri modul asılılığı
   a.alq → b.alq → c.alq → a.alq

   = kömək: ortaq hissəni ayrıca modula çıxarın

Həlli: interfeysi ayrıca modula çıxarmaq, və ya gətirDinamik() istifadə etmək.


8.7 Paket quruluşu#

mənim-layihəm/
├── layihe.alq              # paket manifesti
├── alqor.kilid               # dəqiq versiya kilidi (avtomatik)
├── mənbə/
│   ├── əsas.alq            # giriş nöqtəsi
│   ├── model/
│   │   ├── indeks.alq      # `gətir ./model` bunu yükləyir
│   │   ├── istifadəçi.alq
│   │   └── sifariş.alq
│   └── xidmət/
│       └── auth.alq
├── sınaq/
│   ├── istifadəçi_sınaq.alq
│   └── auth_sınaq.alq
├── statik/                   # veb üçün statik fayllar
│   ├── üslub.css
│   └── şəkil/
├── sənəd/
├── paketlər/                 # asılılıqlar (alqorpm yükləyir)
└── qurma/                    # kompilyasiya nəticələri
    ├── linux-x64/
    ├── veb/
    └── paket/

8.8 layihe.alq — manifest faylı#

Format TOML-a bənzəyir, amma iki fərqi var: açarlar Azərbaycan hərfli ola bilər (açarSözlər, sərt_boş — TOML 1.0-da qadağandır) və məntiqi dəyərlər doğru/yanlış yazılır (true/false da qəbul olunur). Dəstəklənən: [bölmə], [bölmə.alt], mətn ("…", '…'), tam və onluq ədəd, massiv (çoxsətirli də), sətirdaxili cədvəl { … }, dırnaqlı açar, # şərhi. Xəta mesajı sətir nömrəsini göstərir.

toml
[paket]
ad = "mənim-layihəm"
versiya = "1.0.0"
təsvir = "Nümunə Alqor layihəsi"
müəllif = ["Vüqar Qənbərov <vuqar@nümunə.az>"]
lisenziya = "MIT"
depo = "https://github.com/istifadəçi/mənim-layihəm"
sənəd = "https://vuqar.pro/hub/paket/mənim-layihəm"
açarSözlər = ["veb", "api"]
alqor_versiya = ">=1.0.0"

[qurma]
giriş = "mənbə/əsas.alq"
hədəf = ["linux-x64", "veb"]      # linux-x64 | linux-arm64 | veb | wasm | windows-x64 | macos-arm64
çıxış = "qurma/"
optimallaşdırma = 2                # 0=yox 1=sürətli 2=balanslı 3=maksimum
simvollar = yanlış                 # sazlama simvolları
statik = doğru                     # statik bağlama (asılılıqsız binar)
sıxılma = doğru

[tip]
rejim = "normal"                   # sərbəst | normal | sərt
sərt_boş = doğru                   # ixtiyari tiplər məcburi yoxlanır

[icra]
stek_dərinliyi = 8192
zibil_yığıcı = "nəsilli"           # istinad | nəsilli | yoxdur
yaddaş_limiti = "512MB"

[asılılıqlar]
veb = "2.1"
verilənlər = "^3.0"                # 3.x.x
json = "~1.4.2"                    # 1.4.x
"@şirkət/analitika" = "1.0"
yerli_paket = { yol = "../yerli" }
qit_paket = { qit = "https://github.com/a/b", teq = "v1.0" }

[inkişaf_asılılıqları]
sınaq_köməkçi = "1.0"

[sınaq]
qovluq = "sınaq/"
örtük_minimum = 80

[veb]
port = 8080
host = "0.0.0.0"
statik_qovluq = "statik/"
canlı_yeniləmə = doğru

[desktop]
pəncərə_başlıq = "Mənim Proqramım"
en = 1024
hündürlük = 768
ikon = "statik/ikon.png"
dəyişdirilə_bilən = doğru

[paketləmə]
deb = { ad = "menim-layihem", asılılıqlar = ["libwebkit2gtk-4.1-0"] }
appimage = { kateqoriya = "Utility" }
flatpak = { id = "az.numune.MenimLayihem" }
docker = { baza = "debian:bookworm-slim" }

[skriptlər]
başlat = "alqor işlət mənbə/əsas.alq"
qur = "alqor qur --buraxılış"
sınaq = "alqortest"
format = "alqorfmt ."

8.9 alqorpm — paket meneceri ✅#

terminal
alqorpm başlat                      # yeni layihə yarat
alqorpm əlavə veb                   # paket əlavə et
alqorpm əlavə veb@2.1               # konkret versiya
alqorpm əlavə --inkişaf sınaq_köməkçi
alqorpm sil veb                     # paket sil
alqorpm yüklə                       # layihe.alq-dakı hamısını yüklə
alqorpm yenilə                      # asılılıqları yenilə
alqorpm yenilə veb                  # bir paketi yenilə
alqorpm siyahı                      # quraşdırılmışları göstər
alqorpm ağac                        # asılılıq ağacı
alqorpm axtar json                  # alqorhub-da axtar
alqorpm məlumat veb                 # paket haqqında
alqorpm təmizlə                     # keşi təmizlə
alqorpm yoxla                       # təhlükəsizlik auditi
alqorpm yayımla                     # alqorhub-a göndər
alqorpm giriş                       # alqorhub hesabına giriş

Əlavə əmrlər: alqorpm paketlə (arxivi yayımlamadan yoxlamaq), alqorpm qeydiyyat / çıxış, alqorpm geri-çək ad@1.0.1 (versiya silinmir, yeni layihələr onu seçmir), alqorpm versiya patch|minor|major, alqorpm işlət <skript> ([skriptlər] bölməsi). alqor pm … də eynidir.

Yol və qit asılılıqları:

terminal
alqorpm əlavə yerli --yol ../yerli
alqorpm əlavə util --qit https://github.com/a/b --teq v1.0

Kilid faylı (alqor.kilid) hər paketin dəqiq versiyasını, mənbəyini və arxivin SHA256 həzmini saxlayır; alqorpm yüklə başqa kompüterdə də eyni versiyaları quraşdırır, həzm uyğun gəlməsə ALQ-M010 verir. Ziddiyyətli tələblər (b → a ^1, c → a ^2) kimin nəyi tələb etdiyini göstərən ALQ-M007 ilə bitir.

Depo ünvanı: --depo URL › ALQORHUB › layihe.alq [alqorpm] depo › ~/.alq/ayarlar.json › https://vuqar.pro/hub.

alqorhub — paket deposu ✅#

terminal
alqor hub --qovluq hub-məlumat --port 8790 --admin aysel

Rəsmi depo https://vuqar.pro/hub alt ünvanında işləyir. Bunun üçün --önək /hub: səhifə linkləri və API-nin qaytardığı arxiv ünvanları önəklə qurulur; reverse proxy önəki silsə də, saxlasa da işləyir. X-Forwarded-Proto / X-Forwarded-Host başlıqları nəzərə alınır:

terminal
alqor hub --qovluq /srv/alqorhub --host 127.0.0.1 --port 8790 --önək /hub
nginx
location /hub/ {
    proxy_pass http://127.0.0.1:8790/hub/;
    proxy_set_header Host $host;
    proxy_set_header X-Forwarded-Proto $scheme;
    client_max_body_size 12m;
}

Xarici asılılıqsız server (SQLite + fayllar): veb səhifələr (axtarış, README, versiyalar), JSON API (/api/paketlər, /api/paket/<ad>, /api/paket/<ad>/<versiya>/fayl, PUT ilə yayım, geri-çək, sahib, qeydiyyat, giriş, xəbərdarlıqlar). Qaydalar: versiya dəyişməzdir (təkrar yayım 409), ilk yayımlayan sahibdir, arxivdəki manifest URL ilə üst-üstə düşməlidir, ../keçid/cihaz faylı rədd edilir, parollar scrypt ilə saxlanır.

Versiya sintaksisi#

YazılışMənası
=1.2.3dəqiq bu versiya
1.2.3, 1.2^ kimi (uyğun yeniləmələr)
^1.2.3>=1.2.3 <2.0.0 (uyğun yeniləmələr)
~1.2.3>=1.2.3 <1.3.0 (yalnız yamaqlar)
>=1.2bu və daha yuxarı
1.2.*1.2.x
*istənilən
1.0 || 2.0ya biri, ya digəri

8.10 Ad həlli sırası#

gətir X ifadəsi belə axtarır:

  1. Standart kitabxana modulları (nüvə, mətn, riyaziyyat, ...)
  2. Layihənin mənbə/ qovluğu
  3. paketlər/ qovluğu (yerli asılılıqlar)
  4. Qlobal keş: ~/.alq/paketlər/
  5. Sistem: /usr/lib/alqor/paketlər/

Tapılmasa: ALQ-M001. gətir python:X bu sıraya daxil deyil — Python modulu Python-un öz idxal sistemi ilə axtarılır (§ 8.14).


8.11 Ad münaqişələri#

Alqor
gətir riyaziyyat.{kök}
gətir həndəsə.{kök}              // ✖ ALQ-M006 ad münaqişəsi

// Həlli:
gətir riyaziyyat.{kök kimi riyaziKök}
gətir həndəsə.{kök kimi həndəsiKök}

// Və ya:
gətir riyaziyyat
gətir həndəsə
yaz(riyaziyyat.kök(16))
yaz(həndəsə.kök(düyün))

8.12 Görünüş#

ModifikatorGörünür
(yoxdur)yalnız həmin fayl
ixrac etidxal edən hər kəs
ixrac et modulyalnız eyni paket daxilində
Alqor
ixrac et modul funksiya daxiliAPI()     // paket daxilində açıq, kənarda gizli
    ...
son

8.13 Modul xəta kodları#

KodMesaj
ALQ-M001Modul tapılmadı
ALQ-M002Modulda belə ixrac yoxdur
ALQ-M003İxrac olunmayan üzvə müraciət
ALQ-M004Yanlış modul yolu
ALQ-M005Dövri modul asılılığı
ALQ-M006İdxalda ad münaqişəsi
ALQ-M007Versiya uyğunsuzluğu
ALQ-M008layihe.alq tapılmadı
ALQ-M009layihe.alq formatı pozulub
ALQ-M010Paket imzası doğrulanmadı
ALQ-M011⚠ İstifadə olunmayan idxal
ALQ-M012⚠ gətir * tövsiyə olunmur
ALQ-M013Python paketi tapılmadı (alqor python qur …)
ALQ-M014Python istisnası — PythonXətası
ALQ-M015Python kitabxanaları bu hədəfdə işləmir (JS, veb, alqor-rs)

8.14 Python kitabxanaları ✅#

Alqor-un əsas icraçısı Python-da yazılıb, ona görə istənilən Python modulu — standart kitabxana və ya PyPI-dən quraşdırılmış paket — birbaşa idxal oluna bilər. Alqor beləliklə PyPI-nin bütün ekosistemini (numpy, requests, pandas, pillow …) dərhal əldə edir.

Sintaksis#

python: prefiksi gətir-in bütün formaları ilə işləyir:

Alqor
gətir python:numpy kimi np                    // bütöv modul, ləqəblə
gətir python:os.path                          // alt modul → `path` adı
gətir python:math.{sqrt, pi kimi PI}          // seçmə idxal
gətir python:statistics.*                     // hamısı (tövsiyə olunmur)

python kontekstli sözdür: yalnız gətir-dən sonra və ardınca : gələndə prefiksdir. gətir python (adı python olan Alqor modulu) və dəyişən python = 1 əvvəlki kimi işləyir. Bağlanan ad Alqor qaydasıdır: gətir python:os.path → path (Python-un import os.path → os qaydası yox). Seçmə idxalda {…} içindəki ad modulun üzvü deyilsə, alt modul kimi axtarılır (gətir python:xml.{dom}).

İşlətmə#

Alqor
gətir python:collections kimi kol
gətir python:datetime.{date, timedelta}
gətir python:builtins.{sorted}

dəyişən say = kol.Counter("azərbaycan")
yaz(say.most_common(2))                       // [("a", 3), ("z", 1)]
yaz(say["a"])                                 // indeks

dəyişən g = date(2025, 3, 20) + timedelta(days: 40)   // adlı arqument
yaz(g.isoformat(), g > date(2025, 1, 1))      // operatorlar

hər söz, n üçün kol.Counter(["a", "b", "a"]) içində    // Mapping → lüğət kimi
    yaz(söz, n)
son

yaz(sorted(["alma", "ət"], key: (s) => uzunluq(s)))   // geri çağırış
Alqor əməliyyatıPython qarşılığı
o.ad, o.ad = dgetattr / setattr (paketdə alt modul avtomatik idxal olunur)
f(a, ad: d)f(a, ad=d) — adlı arqumentlər kwargs olur
o[i], o[i] = d__getitem__ / __setitem__
o[1..3], o[1..<3]o[1:4], o[1:3] — Alqor dilimi son həddi daxil edir
hər x üçün o içindəiter(o) (tənbəl; generatorlar da)
x içindədir o, uzunluq(o)x in o, len(o)
+ - * / ~/ % ** & | ^ << >> < > <= >= <=>uyğun Python operatoru (~/ → //)
-o-o
====
o kimi tam/onluq/məntiq/siyahı/dəst, məntiqƏt(o)int / float / bool / list / set
yaz(o), "{o}", mətnƏt(o)str(o)
istifadə f = open("a.txt")with open("a.txt") as f (__enter__/__exit__)
tip(o)python:<sinif adı>, python:modul[ad], python:sinif[ad], python:funksiya[ad]

Alqor şərtləri yalnız məntiq qəbul etdiyindən əgər o əvəzinə əgər o kimi məntiq (Python bool(o)) yazılır.

Çevrilmə qaydaları#

Hər iki istiqamətdə dərin çevrilmə:

AlqorPython
tam, onluq, mətn, məntiq, boş, baytint, float, str, bool, None, bytes
siyahı, lüğət, dəst, kortejlist, dict, set, tuple (frozenset → dəst)
diapazonlist
funksiya, lambda, metodPython çağırıla bilən obyekti
qalan hər şeyproksi (PythonObyekti)
  • int/float alt sinifləri (IntEnum, numpy.int64, numpy.float64) tam/onluq olur.
  • list/dict/tuple-ın alt sinifləri (Counter, OrderedDict, namedtuple, deque) proksi qalır — öz metodları itməsin.
  • Kolleksiyanın heç bir elementi çevrilmə tələb etmirsə, eyni obyekt ötürülür: bisect.insort(s, 4) və random.shuffle(s) Alqor siyahısını yerində dəyişir. Element çevrilibsə (məs. içində Alqor funksiyası var) — surət ötürülür.
  • Alqor funksiyası Python-a ötürüləndə (key: f, geri çağırışlar) arqumentləri Alqor dəyərinə, nəticəsi Python dəyərinə çevrilir. Geri çağırışın atdığı Alqor xətası Python kodundan olduğu kimi keçir (tut (x: BölməXətası) işləyir).

Xətalar#

Python istisnası PythonXətası (Xəta-nın alt tipi, ALQ-M014) olur:

Alqor
cəhd et
    json.loads(mətn)
tut (x: PythonXətası) əgər x.pythonTipi == "JSONDecodeError"
    yaz("pozulmuş JSON:", x.mesaj)    // "JSONDecodeError: Expecting value…"
son
SahəMəna
x.mesaj"<Sinif>: <mesaj>"
x.pythonTipiistisnanın sinif adı ("ValueError")
x.istisnaistisna obyektinin özü (proksi)
x.kod"ALQ-M014"

Quraşdırılmamış paket: ALQ-M013, mesaj quraşdırma əmrini göstərir:

✖ ALQ-M013  PythonXətası: `numpy` Python paketi tapılmadı — `alqor python qur numpy` ilə quraşdırın

İdxal adı pip adından fərqli olan məşhur paketlər üçün düzgün ad göstərilir (yaml → pyyaml, PIL → pillow, sklearn → scikit-learn, cv2 → opencv-python, bs4 → beautifulsoup4).

Paketlərin quraşdırılması — alqor python#

Paketlər layihənin (layihe.alq olan qovluğun) python_paketlər/ qovluğuna quraşdırılır — sistem Python-una toxunulmur, layihə öz asılılıqlarını daşıyır. Bu qovluq alqor yeni şablonunun .gitignore faylındadır.

terminal
alqor python qur requests "numpy>=2"   # pip install --target python_paketlər/
alqor python qur                       # layihe.alq → [python] asılılıqlar
alqor python siyahı                    # quraşdırılmışlar: ad==versiya
alqor python sil requests              # RECORD siyahısına görə silir
alqor python qur --no-index --find-links ./təkərlər paket   # internetsiz
alqor python siyahı --qovluq q/        # layihəsiz: istənilən qovluq

- ilə başlayan seçimlər pip-ə ötürülür (--find-links Q, --index-url URL, --pre, --no-deps …); ---dan sonrakı hər şey də.

toml
[python]
asılılıqlar = ["requests>=2.31", "numpy"]
# və ya: asılılıqlar = { requests = ">=2.31", numpy = "*", rich = "13.7" }
#        (versiya operatorsuz yazılsa `==` sayılır)

İdxal yolu. gətir python:X icra olunanda sys.path-a (sistem paketlərindən öndə, venv kimi) əlavə olunur:

  1. ALQOR_PYTHON_YOLU mühit dəyişənindəki qovluqlar (os.pathsep ilə);
  2. idxal edən fayldan yuxarı ilk layihe.alq-un yanındakı python_paketlər/.

Sonra Python-un adi axtarışı (sistem site-packages daxil) gəlir.

pip. Alqor-un quraşdırıcılarındakı daxili Python (python-build-standalone) pip-i daxil edir. pip yoxdursa alqor python qur əvvəlcə python -m ensurepip ilə quraşdırmağa çalışır; alınmasa nə etmək lazım olduğunu yazır (məs. Debian/Ubuntu: sudo apt install python3-pip). --target quraşdırması PEP 668 ("externally managed") qadağasına düşmür.

Paketləmə — alqor qur#

alqor qur (.pyz) və alqor qur --exe layihənin python_paketlər/ qovluğunu paketə daxil edir; işə salınanda o, keş qovluğuna açılır və sys.path-a düşür.

  • Təmiz Python paketləri (py3-none-any təkərləri) hər platformada işləyir.
  • İkili (C uzantılı) təkərlər (numpy, pillow …) yalnız quraşdırıldıqları platforma + arxitektura + Python versiyası üçündür. Linux-da qurulan .exe üçün Windows təkərlərini ayrıca layihə surətində pip seçimləri ilə quraşdırın: alqor python qur --platform win_amd64 --only-binary=:all: --python-version 3.12 numpy (daxili Python 3.12-dir).

Məhdudiyyətlər#

  • Yalnız əsas (Python) icraçısı: alqor işlət --js, veb hədəfi (alqor qur --hədəf js|veb) kompilyasiya xətası verir — "Python kitabxanaları JS hədəfində işləmir"; alqor-rs icra xətası verir (ALQ-M015).
  • Tip yoxlayıcısı Python obyektlərini istənilən sayır (yoxlama yoxdur). gətir python:X.* üçün adları bilmək məqsədilə yoxlayıcı modulu idxal edir.
  • Python async korutinləri Alqor gözlə-si ilə gözlənilmir — asyncio.run(...) işlədin.
  • Kontekst menecerinin __exit__-i xətanı "uda" bilməz — xəta yenə atılır.
  • Python-dan qayıdan kolleksiya surətdir (elementləri çevrilibsə); obyektin daxili siyahısını dəyişmək üçün onun öz metodlarını çağırın.
  • Python kodu Alqor-un təhlükəsizlik zəmanətlərindən kənardadır: quraşdırdığınız paketə etibar etməlisiniz (PyPI-dəki hər paket kimi).