Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Salut, Habr! Vă prezint traducerea postării lui Stephen Wolfram „Repository-ul de Funcții Wolfram: Lansarea unei Platforme Deschise pentru Extinderea Limbajului Wolfram”.

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Premisele viabilității limbajului Wolfram

Astăzi ne aflăm la pragul unor realizări mari împreună cu limbajul de programare Wolfram Language. Cu doar trei săptămâni în urmă am lansat un motor Wolfram gratuit pentru dezvoltatori, pentru a ajuta utilizatorii noștri să integreze limbajul Wolfram Language în proiectele lor mari de software. Chiar astăzi lansăm repository-ul de funcții Wolfram, pentru a oferi o platformă coordonată pentru funcțiile create pentru extinderea limbajului Wolfram, precum și deschidem un repository de funcții pentru oricine poate contribui la dezvoltarea produsului nostru software.

Repository-ul de Funcții (Function Repository) Wolfram este ceea ce a devenit posibil datorită specificului unic al Wolfram Language nu doar ca limbaj de programare, ci și ca limbaj de calcul complet. În limbajele tradiționale de programare, adăugarea unor funcții noi semnificative implică, de obicei, crearea unor biblioteci suplimentare întregi, care pot funcționa sau nu în cadrul unor utilizări comune. Totuși, în limbajul Wolfram Language sunt deja atât de multe integrate în limbajul în sine, încât există posibilitatea de a extinde semnificativ funcționalitatea sa, pur și simplu prin adăugarea de noi funcții, care se integrează imediat în structura întregului limbaj.

De exemplu, deja în repository-ul de funcții Wolfram există 532 noi funcții structurate pe 26 de categorii tematice:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Asemănător cu cele peste 6000 de funcții standard, integrate în limbajul Wolfram, fiecare funcție din repository are o pagină de documentație cu descrieri detaliate și exemple de utilizare:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Pentru a accesa pagina, copiați obiectul de mai sus (BLOB funcțional), lipiți-l în linia de input și apoi rulați funcția – aceasta este deja integrată în limbajul Wolfram și este suportată implicit, începând cu versiunea 12.0:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Aici trebuie menționat că, la procesarea LogoQRCode Nu trebuie, de exemplu, să configurați „biblioteca pentru procesarea imaginilor” — deoarece în limbajul Wolfram Language am implementat deja un mod secvențial și riguros algoritmizat de procesare a imaginilor, care pot fi procesate imediat prin diferite funcții grafice ale limbajului:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Sper că cu sprijinul unei comunități minunate și talentate, care a crescut și s-a extins (pe baza limbajului Wolfram) de-a lungul ultimelor câteva decenii. Repozitoriul funcțiilor Wolfram va permite în viitorul apropiat să extindă semnificativ gama (posibil potențial semnificativă, specializată în diferite domenii de știință și tehnică) a funcțiilor disponibile în limbaj. Astfel, devine posibil să folosiți atât conținutul limbajului (funcțiile sale încorporate), cât și principiile de dezvoltare, care se implementează pe baza limbajului. (Aici merită menționat că Wolfram Language are deja o istorie de mai bine de 30 de ani de dezvoltare și creștere constantă).
În interiorul funcțiilor din repozitoriu pot exista fragmente mici sau suficient de mari de cod scris în limbajul Wolfram. De exemplu, acestea pot fi apeluri la API-uri externe și servicii sau biblioteci externe în alte limbaje. O caracteristică unică a acestei abordări este că, atunci când treceți la funcționalitatea la nivel de utilizator, vor lipsi posibilele neconcordanțe din cauza faptului că această abordare se bazează pe o structură coerentă a limbajului Wolfram — și fiecare funcție va fi automat corectă — exact așa cum ar trebui să fie.
Interfața și structura software a repozitorului de funcții Wolfram sunt configurate astfel încât oricine să poată contribui la cauza comună într-un mod cât mai simplu și confortabil pentru el — practic, prin completarea unui fișier text de tip notebook (cu extensia nb) WL. Funcțiile automate încorporate permit verificarea noilor funcții adăugate în repozitoriu pentru a asigura integrarea garantată în limbaj. Compania noastră pune accent pe un cerc amplu de utilizatori care pot integra funcțiile lor în limbaj, nu pe complexitatea mare a noilor funcții — și, deși acest proces de verificare este implementat, nu insistăm asupra așa-ziselor analize meticuloase ale construcției sau standarde stricte de completitudine și fiabilitate a noilor funcții ale utilizatorilor, spre deosebire de verificările mai riguroase ale funcțiilor încorporate în nucleul limbajului, pe care le aplicăm.

Această abordare implică numeroase compromisuri și detalii, dar scopul nostru este să optimizăm depozitul de funcții Wolfram atât pentru confortul utilizatorilor, cât și pentru ca noile funcții ale utilizatorilor să aducă o contribuție semnificativă la dezvoltarea limbajului. Pe măsură ce creștem, nu am nicio îndoială că va trebui să inventăm noi metode de procesare și verificare a funcțiilor încorporate în depozit, și aceasta nu în ultimul rând pentru a organiza un număr mare de funcții și pentru a găsi cele necesare utilizatorilor. Cu toate acestea, nu poate decât să ne încurajeze că drumul ales de noi este un bun început. Eu personal am adăugat câteva funcții în baza inițială. Multe dintre ele se bazează pe codul pe care l-am dezvoltat personal pentru o perioadă îndelungată. Și mi-a luat doar câteva minute să le trimit în depozit. Acum, când sunt în depozit, pot în sfârșit – fără întârziere și oricând – să utilizez aceste funcții după cum am nevoie, fără a mă preocupa de căutarea fișierelor, descărcarea pachetelor etc.

Creșterea eficienței cu reducerea costurilor

Chiar și înainte de apariția Internetului, existau metode de schimb de cod Wolfram Language (primul nostru mare proiect centralizat a fost MathSource, creat pentru Mathematica în 1991 pe baza CD-ROM-ului etc.). Cu siguranță, abordarea propusă bazată pe depozitul de funcții Wolfram reprezintă un mijloc mai puternic și mai fiabil pentru îndeplinirea sarcinilor menționate mai sus.

De mai bine de 30 de ani, compania noastră a muncit din greu pentru a menține integritatea structurii limbajului Wolfram, și acest lucru este foarte important pentru ca limbajul Wolfram să nu devină doar un limbaj de programare, ci și un limbaj de calcul complet. Astfel, esența abordării de implementare a depozitului de funcții Wolfram constă în utilizarea unei singure abordări în programare și dezvoltarea de noi funcții, care sunt adăugate și integrate în cadrul limbajului pentru a-i permite dezvoltarea și evoluția comună.

În structura implementării fiecărei funcții au loc diverse procese computaționale. Aici trebuie menționat că este esențial ca funcția să aibă un aspect clar și uniform pentru utilizator, precum și o lizibilitate evidentă. În acest context, funcțiile încorporate ale limbajului Wolfram Language sunt prezentate prin peste 6000 de exemple secvențiale despre cum ar trebui să se programeze corect funcțiile (acestea sunt recenziile video despre programare în timp real, care includ sute de ore de proces de creare a programelor tipice). Această abordare permite în cele din urmă ca depozitul de funcții Wolfram să funcționeze eficient, având în vedere natura structurală a limbajului Wolfram Language, cu numeroase biblioteci suplimentare și diverse, deja încorporate în limbaj. De exemplu, dacă aveți o funcție care procesează imagini sau matrici sparse, sau structuri moleculare, dar și pentru date geografice sau alte tipuri — în limbajul există deja o reprezentare simbolică coerentă, iar datorită acestui fapt funcția dumneavoastră devine imediat compatibilă cu alte funcții din limbaj.

Crearea unui depozit care să funcționeze cu adevărat bine reprezintă o provocare interesantă de meta-programare. De exemplu, un exces de constrângeri în program nu va permite obținerea uniformizării și universalității necesare funcționării algoritmului. La fel ca și în cazul unui număr insuficient de constrângeri funcționale, nu veți putea implementa o succesiune de execuție a algoritmului suficient de corectă. Câteva exemple anterioare de implementare a compromisurilor acestor abordări, realizate de compania noastră, au funcționat destul de stabil — acestea sunt: Proiectul Wolfram Demonstrații, lansat în 2007 și acum funcționând în mod interactiv pe internet, conținând peste 12000 de demonstrații interactive create de utilizatori. În baza de date Wolfram există peste 600 de baze de date gata de utilizare în limbajul Wolfram Language, iar depozitul de rețele neuronale Wolfram se îmbogățește cu rețele neuronale noi aproape în fiecare săptămână (în prezent sunt deja 118) și acestea sunt conectate imediat prin funcția NetModel în limbajul Wolfram Language.

Toate exemplele menționate mai sus au o caracteristică esențială - obiectele și funcțiile adunate într-un proiect au un grad foarte ridicat de structurare și distribuție a proceselor. Cu siguranță, detalierea structurii a ceea ce reprezintă o demonstrație sau o rețea neurală sau altceva poate varia semnificativ, dar structura fundamentală pentru orice depozit curent rămâne întotdeauna neschimbată. Care este, așadar, părerea dumneavoastră, stimate utilizator, despre crearea unui astfel de depozit care adaugă extensii la limbajul Wolfram? Limbajul Wolfram Language este proiectat pentru a fi extrem de flexibil, așadar poate fi extins și modificat în orice mod. Această circumstanță este extrem de importantă pentru capacitatea de a crea rapid diverse proiecte software de mari dimensiuni folosind limbajul Wolfram Language. Aici trebuie menționat că, pe măsură ce flexibilitatea limbajului crește, inevitabil vor crește și costurile proiectelor realizate în acest limbaj. Acest lucru se întâmplă deoarece, cu cât utilizatorul aplică acest limbaj, cu atât mai multă funcționalitate dedicată obține, dar nu trebuie uitat că această abordare poate avea și părți negative în ceea ce privește imposibilitatea de a asigura coerența constantă a modulelor software.

În limbajele tradiționale de programare există o problemă comună legată de biblioteci - dacă, de exemplu, utilizați o bibliotecă, codul funcționează corect, dar, dacă încercați să utilizați mai multe biblioteci, nu există nicio garanție că acestea vor interacționa corect între ele. De asemenea, în limbajele tradiționale de programare - în contrast cu un limbaj complet de calcul - lipsesc posibilitățile de a controla garantat existența unor reprezentări integrate și coerente pentru orice funcții sau tipuri de date, în afară de structurile lor de bază. Dar, în esență, problema este chiar mai mare decât pare la prima vedere: dacă cineva construiește o verticală de funcționalitate pe scară largă, fără cheltuieli enorme pentru programarea centralizată a proiectului, pe care l-am investit în limbajul Wolfram, nu este posibil să se atingă coerența. Prin urmare, este important ca toate modulele software să funcționeze întotdeauna corect împreună.

Astfel, ideea depozitului de funcții Wolfram este de a evita problema expusă mai sus - adăugând pur și simplu extensii la limbaj sub formă de elemente de cod de dimensiuni relativ mici prin funcții separate, a căror dezvoltare, sub formă de module coerente, este o sarcină mai simplă. Există însă particularități în programare care nu pot fi făcute convenabile prin intermediul funcțiilor separate (iar compania noastră are în plan să lanseze în curând un algoritm software optimizat pentru a ajuta la implementarea pachetelor software la scară largă). Totuși, pe baza funcțiilor deja incluse în Wolfram Language, există numeroase oportunități de programare realizate pe baza funcțiilor separate. Aici, gândul este să se poată crea o serie de funcții noi, foarte utile, cu un efort programativ relativ mic, care să asigure o consistență suficientă a proiectului, fiind în același timp bine coordonate între ele și având capacitatea de a fi utilizate ușor și pe scară largă în limbaj pe viitor.

Această abordare este, fără îndoială, un compromis. În cazul realizării unui pachet mai amplu, ne putem imagina o lume complet nouă de funcționalitate, care va deveni incredibil de puternică și utilă. Dacă există necesitatea de a obține noi capacități funcționale care să se integreze în tot restul, dar nu sunteți pregătit să depuneți eforturi enorme în dezvoltarea proiectului, asta poate duce, din păcate, la o reducere a scalei proiectului dumneavoastră. Ideea depozitului de funcții Wolfram constă în a oferi funcționalități definitorii pentru proiect, această abordare permițând adăugarea unei funcționalități puternice, în același timp simplificând menținerea unei bune coerențe a programării proiectului.

Asistență pentru adăugarea funcțiilor personalizate în depozitul de funcții

Specialiștii companiei noastre au lucrat din greu pentru a face contribuția la funcțiile depozitului Wolfram suficient de ușoară pentru utilizatori. Pe desktop (deja în versiunea 12.0), Puteți naviga pur și simplu prin tab-urile din meniul principal: File > New > RepositoryItem > Function Repository Item și veți obține „Definiție Notebook» (în mod programatic în cadrul mediului de lucru. De asemenea, puteți utiliza funcția similară — CreateNotebook[„FunctionResource”]):

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Există două acțiuni principale pe care va trebui să le efectuați: în primul rând, trebuie să scrieți efectiv codul funcției dumneavoastră și, în al doilea rând, să scrieți documentația care ilustrează cum ar trebui să funcționeze funcția dumneavoastră.
Apăsați butonul „Deschideți exemplul” din partea de sus pentru a vedea un exemplu al a ceea ce trebuie să faceți:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

De fapt, încercați să creați ceva similar unei funcții încorporate în limbajul Wolfram. Cu excepția faptului că aceasta poate face ceva mult mai specific decât o funcție încorporată. În acest sens, așteptările cu privire la completitudinea și fiabilitatea sa vor fi mult mai scăzute.
Trebuie să specificați un nume pentru funcția dumneavoastră, care să respectă principiile de denumire a funcțiilor din limbajul Wolfram. În plus, va trebui să dezvoltați documentația pentru funcția dumneavoastră, similar cu funcțiile încorporate ale limbajului. Voi detalia mai mult despre acest lucru mai târziu. Acum, vă rog să observați că în rândul butoanelor din partea de sus a fișierului notebook de definiții există un buton „Recomandări de stil”, care explică ce trebuie să faceți, și butonul „Instrumente”, care oferă uneltele pentru formatul documentației funcției dumneavoastră.
Când sunteți sigur că totul este complet și sunteți gata, apăsați butonul „Check” („Verificați”). Este perfect normal să nu fiți familiarizat cu toate detaliile. De aceea, funcția „Check” va fi executată automat și va efectua multe verificări de stil și consistență. Adesea, aceasta vă va propune să acceptați și să confirmați corecturile (de exemplu: „Această linie ar trebui să se încheie cu două puncte” și va sugera să introduceți două puncte). Uneori, vă va cere să adăugați sau să modificați ceva singuri. Vom continua să adăugăm noi funcționalități automatizate butonului „Check”, dar în principal scopul său este de a garanta – tot ceea ce trimiteți în repository-ul funcțiilor este deja conform cât mai multor recomandări de stil.

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Așadar, după ce ați apăsat pe „Check”, puteți utiliza „Preview” („Previzualizare”). „Preview” creează o previzualizare a paginii de documentație pe care ați definit-o pentru funcția dumneavoastră. De asemenea, puteți crea o previzualizare pentru un fișier creat pe computerul dumneavoastră sau pentru un fișier stocat în cloud. Dacă, din diverse motive, nu sunteți mulțumit de ceea ce vedeți în previzualizare, reveniți și efectuați corecțiile necesare, după care apăsați din nou butonul Preview.
Acum sunteți gata să publicați funcția în repository. Butonul Deploy vă oferă patru opțiuni de acțiune:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

În acest pas, este important să rețineți că puteți trimite funcția dumneavoastră în repository-ul funcțiilor Wolfram, astfel încât să fie accesibilă oricărui utilizator. De asemenea, puteți să publicați funcția pentru un număr limitat de utilizatori. De exemplu, puteți crea o funcție locală pe computerul dumneavoastră, astfel încât să fie disponibilă atunci când utilizați acest computer specific. Sau o puteți publica în contul dumneavoastră din cloud, astfel încât să fie accesibilă atunci când sunteți conectat la cloud. De asemenea, puteți publica (distribui) funcția în mod public prin contul dumneavoastră din cloud. Aceasta nu va apărea în repository-ul central al funcțiilor Wolfram, dar veți putea oferi cuiva URL-ul care le va permite să obțină funcția dumneavoastră din contul dumneavoastră. (În viitor, vom susține și repository-uri centrale la scară întreagă în compania noastră).

Așadar, să presupunem că doriți să transferați efectiv funcția dumneavoastră în baza de cunoștințe a funcțiilor Wolfram. Pentru aceasta, apăsați butonul „Trimiteți” în repository. Ce se întâmplă în acel moment? Cererea dumneavoastră intră imediat în așteptare pentru revizuire și aprobată de echipa noastră specializată de curatori.

Pe măsură ce cererea dumneavoastră trece prin procesul de aprobat (care durează de obicei câteva zile), veți primi mesaje cu privire la statutul examinării acesteia, precum și, posibil, propuneri pentru utilizarea sa ulterioară. Însă, imediat ce funcția dumneavoastră va fi aprobată, aceasta va fi publicată instantaneu în repository-ul de funcții Wolfram și va deveni disponibilă pentru orice utilizare. (Și acest lucru va fi afișat în buletinele de știri despre noile funcții etc.)

Ce ar trebui să conțină repository-ul?

Trebuie menționat că compania noastră are standarde foarte înalte de completitudine, fiabilitate și calitate generală, dintre cele 6000+ de funcții pe care le-am integrat în limbajul Wolfram în ultimi 30 de ani, toate respectă cerințele menționate anterior. Scopul repository-ului de funcții Wolfram este de a utiliza întreaga structură și capacitățile funcționale care există deja în Wolfram Language, pentru a adăuga cât mai multe funcții mult mai ușoare (adică funcții cu o performanță mai bună).

Desigur, funcțiile din repository-ul de funcții Wolfram trebuie să respecte principiile de dezvoltare ale limbajului Wolfram Language — pentru a putea interacționa pe deplin cu alte funcții și a îndeplini așteptările utilizatorilor cu privire la modul în care funcțiile ar trebui să funcționeze corect. Cu toate acestea, funcțiile nu trebuie să aibă aceeași completitate sau fiabilitate.

În funcțiile integrate ale limbajului Wolfram, lucrăm din greu pentru a face funcțiile software cât mai generale posibil. Totuși, nu este nimic greșit în faptul că în repository-ul de funcții Wolfram poate fi inclusă o funcție care numai procesează un caz foarte specific, dar util. De exemplu, funcția SendMailFromNotebook poate primi fișiere într-un anumit format și crea e-mailuri într-un anumit mod. PolygonalDiagram creează diagrame doar cu anumite culori și etichetări etc.

Un alt aspect legat de funcțiile încorporate este că compania noastră depune toate eforturile pentru a gestiona toate cazurile atipice, pentru a trata corect intrările incorecte și așa mai departe. În repository-ul de funcții, este absolut normal ca să existe o funcție specială care gestionează cazurile de bază ale problemei și ignoră toate celelalte.

Este evident că este mai bine să ai funcții care fac mai mult și fac asta mai bine, dar optimizarea pentru repository-ul de funcții — spre deosebire de funcțiile încorporate ale limbajului Wolfram — ar trebui să aibă mai multe funcții legate de un număr mai mare de funcții, decât să se aprofundeze în procesele de implementare a fiecărei funcții specifice.

Acum să luăm în considerare un exemplu de testare a funcțiilor din repository. Așteptările de coerență pentru astfel de funcții sunt în mod natural mult mai scăzute decât pentru funcțiile încorporate ale limbajului. Acest lucru este și mai relevant în cazurile în care funcțiile depind de resurse externe, cum ar fi API-urile, este important să efectuezi constant teste consistente, ceea ce se întâmplă automat în cadrul algoritmilor de verificare. În fișierul nb poți indica explicit definițiile (în secțiunea „Informații suplimentare”) și să specifici atât de multe teste câte consideri necesar, definite fie prin linii de intrare și ieșire, fie prin obiecte complete de tip simbolic. VerificationTest, câte consideri că sunt necesare. În plus, sistemul încearcă constant să transforme exemplele de documentație pe care le-ai furnizat în procese de verificare (uneori, acest lucru poate fi destul de consumator de resurse, de exemplu, pentru o funcție al cărei rezultat depinde de numere aleatorii sau de ora din zi).

În concluzie, în repository-ul de funcții vor exista o serie întreagă de dificultăți de implementare. Unele vor fi doar o linie de cod, altele pot include mii sau zeci de mii de linii, probabil folosind multe funcții auxiliare. În ce cazuri ar trebui să adaugi o funcție, pentru definirea căreia este necesar foarte puțin cod? În principiu, dacă pentru funcție există un nume mnemonic bun, pe care utilizatorii l-ar înțelege cu ușurință văzându-l în partea de cod, atunci poate fi adăugat. În caz contrar, probabil că ar fi mai bine să scrieți din nou codul în programul dvs. de fiecare dată când trebuie să-l utilizați.

Principala scop al depozitului de funcții (după cum sugerează și numele său) este de a introduce noi funcții în funcționalitatea limbajului. Dacă doriți să adăugați noi date sau noi entități, utilizați depozitul Wolfram Data. Dar ce se întâmplă dacă doriți să introduceți noi tipuri de obiecte pentru calculele dvs.?

De fapt, există două moduri. S-ar putea să doriți să introduceți un nou tip de obiect care va fi folosit în noi funcții în depozitul de funcții. În acest caz, puteți să-i scrieți pur și simplu reprezentarea simbolică și să o folosiți când introduceți sau ieșiți funcții în depozitul de funcții.

Dar ce se întâmplă dacă doriți să reprezentați un obiect și apoi să-l definiți prin funcțiile existente în limbajul Wolfram, care ar trebui să funcționeze împreună cu acesta? Pentru aceasta, limbajul Wolfram a avut întotdeauna un mecanism simplu, denumit UpValues. Cu anumite limitări (în special pentru funcțiile care nu pot evalua argumentele lor), depozitul de funcții vă permite să reprezentați pur și simplu o funcție și să definiți valori pentru aceasta. (Pentru a spori așteptările de coerență atunci când creați o nouă construcție importantă, complet integrată în întreg limbajul Wolfram, aceasta este, de obicei, o procedură foarte importantă care nu poate fi realizată doar prin creșterea costului proiectului și aceasta este ceea ce compania noastră face în cadrul proiectelor de dezvoltare pe termen lung ale limbajului, această sarcină nu reprezintă un obiectiv care să fie atins în cadrul dezvoltării depozitului).

Deci, ce ar putea conține codul funcțiilor din depozitul de funcții? Tot ce este integrat în limbajul Wolfram, desigur (cel puțin dacă nu reprezintă amenințări pentru siguranței și funcționalității programului propriu-zis, ca mediu de calcul) la fel ca orice funcție din depozitul de funcții. În același timp, există și alte moduri de funcționare: o funcție din depozitul de funcții poate apela API-uri, fie în Wolfram Cloud, sau din alte surse. Desigur, există anumite riscuri asociate cu aceasta. Din cauza absenței unor garanții că API-ul nu se va schimba, iar funcția din depozitul de funcții va înceta să funcționeze. Pentru a identifica astfel de probleme, există o notă pe pagina de documentație (în secțiunea „Cerințe”) pentru orice funcție care se bazează nu doar pe funcționalitatea încorporată a Wolfram Language. (Desigur, atunci când vine vorba de date reale, pot apărea probleme chiar și cu o astfel de funcționalitate — deoarece datele reale despre lume se schimbă constant, iar uneori chiar se schimbă definițiile și structura acestora.)

Trebuie ca tot codul pentru depozitul de funcții Wolfram să fie scris în limbajul Wolfram? Definitiv, codul din cadrul API-ului extern nu trebuie să fie scris în limbajul Wolfram, ceea ce de fapt nu face ca acel cod să fie cod de limbaj. De fapt, dacă găsiți o funcție practic într-un limbaj sau bibliotecă externă, veți putea crea un wrapper care să permită utilizarea acesteia în depozitul de funcții Wolfram. (De obicei, pentru aceasta ar trebui utilizate funcțiile încorporate ExternalEvaluate sau ExternalFunction în codul limbajului Wolfram.)

Deci, care este sensul de a face asta? Practic, aceasta permite utilizarea întregului sistem integrat Wolfram Language și a întregului său set unificat de capacități software. În cazul în care obțineți o implementare de bază dintr-o bibliotecă externă sau limbaj, atunci puteți utiliza structura simbolică bogată a limbajului Wolfram pentru a crea o funcție de nivel superior prietenoasă, care permite utilizatorilor să folosească destul de ușor orice funcționalitate deja implementată. Cel puțin, aceasta ar trebui să fie capabilă de implementare în lumea perfectă, unde există toate elementele necesare pentru încărcarea bibliotecilor și așa mai departe, în acest caz acestea vor fi rezolvate automat cu ajutorul Wolfram Language. (Trebuie menționat că, în practică, pot apărea probleme cu configurarea limbajelor externe într-un sistem informatic specific, iar în depozitul cloud pot apărea probleme suplimentare de securitate).

Când analizați pentru prima dată bibliotecile externe standard, acestea par adesea prea complexe pentru a fi cuprinse doar prin câteva funcții. Totuși, în multe cazuri, cea mai mare parte a complexității provine din crearea infrastructurii necesare pentru bibliotecă și a tuturor funcțiilor de suport. Cu toate acestea, în Wolfram Language, infrastructura este de obicei deja integrată în pachete, astfel încât nu este nevoie să detaliați toate aceste funcții de suport; trebuie doar să creați funcții pentru câteva „funcții superioare” orientate pe aplicație în bibliotecă.

„Ecosistemul” bazei de cunoștințe

Dacă ați scris funcții pe care le folosiți constant, atunci trimiteți-le în repoziția de funcții Wolfram! Chiar dacă nu se va ajunge la ceva mai mult (evoluția limbajului), vă va fi mult mai convenabil să folosiți funcții pentru uz personal. Este logic să deducem că, dacă utilizați funcțiile constant, este posibil ca și alți utilizatori să le găsească utile.

Desigur, este posibil să vă aflați într-o situație în care nu aveți posibilitatea — sau nu doriți — să împărtășiți funcțiile dvs. sau în cazurile în care obțineți acces la resurse de informații private. Chiar și în aceste cazuri, puteți să desfășurați funcțiile în contul dvs. din cloud, specificând drepturile de acces la acestea. (Dacă organizația dvs. are un cloud privat Wolfram Enterprise, atunci în curând va putea găzdui propriul repo privat de funcții, care poate fi administrat din organizația dvs. și poate impune vizibilitatea sau nu pentru utilizatorii externi.)

Funcțiile pe care le trimiteți în repoziția de funcții Wolfram nu trebuie să fie perfecte; trebuie doar să fie utile. Este un pic similar cu secțiunea „Erori” din documentația clasică Unix — în „Secțiunea definițiilor” există o secțiune „Note ale autorului”, în care puteți descrie limitările, problemele etc. pe care le știți deja despre funcția dvs. În plus, când trimiteți funcția dvs. în repoziție, puteți adăuga note la trimitere, care vor fi citite de o echipă specială de curatori.

După publicarea funcției, pagina sa va avea întotdeauna două linkuri în partea de jos: „Trimite un mesaj despre această funcție” și „Discută în comunitatea Wolfram». Dacă atașați o eticheta (de exemplu, pentru a-mi semnala erorile), puteți bifa o casetă în care se menționează că doriți ca mesajul și informațiile de contact să fie transmise autorului funcției.

Uneori este necesar să folosești doar funcțiile din depozitul de funcții Wolfram, de exemplu, funcțiile integrate, fără a privi în codul lor. Cu toate acestea, dacă doriți să "priviti în interior", în partea de sus există întotdeauna un buton "Caiet de sarcini". Faceți clic pe el, iar dvs. veți obține propria copie a caietului de sarcini original definit, care a fost trimis în depozitul de funcții. Uneori, o puteți folosi doar ca exemplu pentru nevoile dvs. În acest fel, puteți dezvolta și propria modificare a acestei funcții. Este posibil să doriți să salvați funcțiile găsite din depozit pe computerul dvs. sau în contul dvs. din stocarea cloud, sau poate doriți să le trimiteți în baza de cunoștințe a funcțiilor, poate ca o versiune îmbunătățită și extinsă a funcției originale.

În viitor, intenționăm să sprijinim ramificarea stil Git pentru depozitele de funcții, dar momentan încercăm să simplificăm acest proces și avem întotdeauna doar o versiune comună a fiecărei funcții încorporate în limbaj. Cel mai adesea (dacă dezvoltatorii nu renunță la întreținerea funcțiilor dezvoltate de ei și răspund la mesajele utilizatorilor), autorul original al funcției obține controlul asupra actualizărilor acesteia și trimite versiuni noi, care sunt apoi verifyate și, dacă trec prin procesul de verificare, sunt publicate în limbaj.

Să ne gândim la modul în care funcționează "versiunea" funcțiilor dezvoltate. Chiar acum, atunci când folosiți o funcție din depozitul de funcții, definiția sa va fi stocată constant pe computerul dvs. (sau în contul dvs. cloud, dacă utilizați cloud). Dacă există o nouă versiune a funcției, atunci la următoarea utilizare va apărea un mesaj care vă va informa despre aceasta. Și dacă doriți să actualizați funcția la o versiune nouă, o puteți face folosind comanda ResourceUpdate(„Obiectul BLOB funcțional“ de fapt stochează mai multe informații despre versiuni, și în viitor plănuim să facem acest lucru mai accesibil pentru utilizatorii noștri.)

Una dintre caracteristicile minunate ale depozitului de funcții Wolfram este că orice program Wolfram Language poate folosi funcțiile din acesta de oriunde. Dacă programul apare într-un notebook, este adesea convenabil să formatezi funcțiile din depozit sub forma unor „obiecte binare funcționale” ușor de citit (posibil cu un set corespunzător de versiuni).

Întotdeauna poți accesa orice funcție din depozitul de funcții folosind textul ResourceFunction […]. Și este foarte convenabil dacă scrii cod sau scripturi direct pentru Wolfram Engine, de exemplu, cu ajutorul unui IDE sau editor de cod (merită menționat că depozitul de funcții este complet compatibil cu Free Wolfram Engine pentru dezvoltatori).

Cum funcționează?

În interiorul funcțiilor din depozitul Wolfram este posibil cu utilizarea exact aceleași sisteme de resurse ca în toate celelalte depozite existente (depozit de date, Neural Net Repository, colecție de proiecte demo etc.), ca toate celelalte resurse de sistem Wolfram, ResourceFunction se bazează în cele din urmă pe funcția ResourceObject.

Să examinăm ResourceFunction:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

În interior poți vedea anumite informații folosind funcția Information:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Cum funcționează setarea funcției resursă? Cel mai simplu este un caz pur local. Iată un exemplu care ia o funcție (în acest caz, o funcție pură) și o definește ca o funcție resursă pentru sesiunea curentă de lucru în program:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

După ce ai făcut definiția, poți folosi funcția resursă:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Reține că în acest obiect BLOB funcția are un simbol negru Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram. Aceasta înseamnă că funcția BLOB se referă la o funcție resursă în memorie, definită pentru sesiunea curentă. Pentru o funcție resursă care este stocată permanent pe computerul tău sau în contul tău cloud, există un simbol gri Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram. Iar pentru o funcție resursă oficială din depozitul de funcții Wolfram există un simbol portocaliu Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram.

Deci, ce se întâmplă atunci când folosești meniul „Dezvoltare” din notebook-ul de definiție? În primul rând, acesta ia toate definițiile din notebook și din ele creează simbolic ResourceObject). (Și dacă folosiți un IDE text sau un program, atunci îl puteți crea explicit ResourceObject)

Implementarea locală a funcției din depozit pe computerul dumneavoastră se efectuează folosind comanda LocalCache pentru obiectul resursă, pentru a-l salva ca LocalObject în sistemul dumneavoastră de fișiere. Implementarea în contul cloud se efectuează folosind comanda CloudDeploy pentru obiectul resursă, iar implementarea publică în cloud — CloudPublish. În toate cazurile ResourceRegister este de asemenea folosit pentru a înregistra numele funcției resursă, astfel încât ResourceFunction[„name”] va funcționa.

Dacă faceți clic pe butonul Submit pentru Function Repository, ceea ce se întâmplă sub el ResourceSubmit se apelează pe obiectul resursă. (Și dacă folosiți interfața text pentru introducere, puteți apela ResourceSubmit direct.)

În mod implicit, trimiterea se face cu un nume asociat cu identificatorul dumneavoastră Wolfram ID. Dar dacă trimiteți o cerere în numele unui grup de dezvoltatori sau al unei organizații, puteți stabili un identificator de editor separat și folosiți-l în locul acesta ca nume pentru interacțiunile cu vizualizările dumneavoastră.

După ce ați trimis oricare dintre funcțiile dumneavoastră în baza de date a funcțiilor, aceasta va fi pusă în așteptare pentru revizuire. Dacă primiți comentarii ca răspuns, acestea vor fi de obicei sub formă de fișier text cu „celule de comentarii” suplimentare. Puteți verifica întotdeauna starea cererii dumneavoastră accesând portalul participantului din sistemul de resurse. Dar odată ce funcția dumneavoastră va fi aprobată, veți fi notificat (prin e-mail), iar funcția dumneavoastră va fi publicată în depozitul funcțiilor Wolfram.

Unele subtilități în funcționare

La prima vedere, poate părea că puteți pur și simplu să luați un caiet de definiții și să-l plasați literalmente în depozitul de funcții, dar, de fapt, există multe subtilități — și pentru a le gestiona este necesar să efectuați un programare meta destul de complexă, tratând simbolic atât codul care definește funcția, cât și caietul de definiții. Mare parte din aceasta se întâmplă intern, adică „în culise”, dar pot exista unele consecințe care merită înțelese dacă doriți să contribuiți la baza de cunoștințe a funcțiilor.

Prima subtilitate directă: Când completați „Blocnotele definițiilor”, puteți să faceți referire la funcția dvs. peste tot, folosind un nume similar MyFunction, care arată ca un nume obișnuit pentru o funcție în limbajul Wolfram, dar pentru documentația depozitului de funcții acesta este înlocuit ResourceFunction[„MyFunction”] – aceasta este exact ceea ce utilizatorii vor folosi efectiv atunci când lucrează cu funcția.

A doua subtilitate: când creați o funcție de resursă din Blocnotele definițiilor, toate dependențele implicate în definiția funcției trebuie să fie fixate și incluse explicit. Totuși, pentru a asigura că definițiile rămân modulare, totul trebuie plasat într-un spațiu de nume. (Desigur, că funcțiile care fac toate acestea, se află în depozitul de funcții.)

De obicei, nu veți vedea nicio urmă a codului folosit pentru configurarea acestui spațiu de nume. Dar, dacă dintr-un anumit motiv apelați un simbol nedefinit în interiorul funcției dvs., veți observa că acest simbol se află în contextul intern al funcției. Totuși, când se procesează Blocnotele definițiilor, cel puțin simbolul care corespunde funcției în sine este configurat pentru a fi afișat cel mai bine sub formă de BLOB funcțional, nu ca un simbol brut în contextul intern.

Depozitul de funcții este destinat definirii de funcții noi. Și aceste funcții pot avea opțiuni. Adesea, aceste parametrii (de exemplu, Metodă sau ImageSize) vor avea capacitatea de a fi utilizate atât pentru funcții încorporate, cât și pentru cele pentru care există deja simboluri încorporate. Dar, uneori, unei funcții noi ar putea să-i fie necesare opțiuni noi. Pentru a păstra modularitatea, este necesar ca acești parametrii să fie simboluri definite într-un context intern unic (sau ceva similar, funcții de resursă în sine). Pentru simplitate, depozitul de funcții permite stabilirea de opțiuni noi în definiții sub formă de șiruri. Iar pentru confortul utilizatorului, aceste definiții (cu condiția să folosească OptionValue și OptionsPattern) sunt, de asemenea, procesate astfel încât, atunci când se folosesc funcțiile, parametrii pot fi specificați nu numai ca șiruri, ci și ca simboluri globale cu aceleași nume.

Majoritatea funcțiilor îndeplinesc exact ceea ce trebuie să facă de fiecare dată când sunt apelate, dar unele funcții necesită inițializare înainte de a putea funcționa într-o anumită sesiune — și pentru a rezolva această problemă există o secțiune „Inițializare” în cadrul „Definiției”.

Funcțiile din depozit pot folosi alte funcții deja existente în depozit pentru a configura definițiile pentru depozitul de funcții, inclusiv două (sau mai multe) funcții care se referă una la cealaltă, fiind necesar să fie desfășurate în sesiunea dvs. de lucru cu programul, astfel încât să le puteți referi ca ResourceFunction[„name”], apoi puteți crea combinațiile de care aveți nevoie dintre aceste funcții exemple și adăugați o nouă funcție în depozit bazată pe cele deja existente.

Perspective de dezvoltare. Ce ar trebui să se întâmple când depozitul devine cu adevărat mare?

Astăzi noi doar lansăm depozitul de funcții Wolfram, dar în timp ne așteptăm ca volumul și funcționalitatea acestuia să crească semnificativ, iar pe măsură ce se dezvoltă, vor apărea diferite probleme pe care, așa cum deja suspectăm, le putem anticipa.

Prima problemă se referă la numele funcțiilor și unicitatea acestora. Depozitul de funcții este proiectat astfel încât, similar cu funcțiile încorporate în limbajul Wolfram, să se poată face referire la orice funcție din depozit pur și simplu specificându-i numele. Dar acest lucru înseamnă inevitabil că numele funcțiilor trebuie să fie unice la nivel global în întregul depozit, așa că, de exemplu, în depozit poate exista doar una ResourceFunction[„MyFavoriteFunction”].

La prima vedere, acest lucru poate părea o mare problemă, dar este important de înțeles că este, în principal, aceeași problemă ca și în cazul domeniilor de internet sau al etichetelor de rețele sociale. Și adevărul este că în sistem este pur și simplu necesar să existe un registrar — și acesta este unul dintre rolurile pe care compania noastră le va îndeplini pentru baza de cunoștințe despre funcții Wolfram. (Pentru versiunile private ale depozitului, registrarul acestora pot fi administratorii.) Desigur, un domeniu de internet poate fi înregistrat fără a avea nimic pe el, dar în depozitul de funcții, numele unei funcții poate fi înregistrat doar în prezența unei definiții reale a funcției.

O parte din rolul nostru în gestionarea bazei de cunoștințe pentru funcțiile Wolfram este de a ne asigura că numele ales pentru fiecare funcție are sens în raport cu definiția acesteia și că urmează convențiile de denumire ale Wolfram Language. Avem deja peste 30 de ani de experiență în denumirea funcțiilor încorporate în Wolfram Language, iar echipa noastră de curatori va aduce această experiență și în depozitul de funcții. Desigur, există întotdeauna excepții. De exemplu, ar putea părea preferabil să avem un nume scurt pentru o anumită funcție, dar este mai bine să „ne apăram” cu un nume mai lung, mai specific, deoarece există mai puține șanse ca cineva să vrea să creeze un nume de funcție asemănător în viitor.

(Aici trebuie menționat că simpla adăugare a unei etichete pentru participant pentru a elimina ambiguitatea funcțiilor nu va aduce efectul așteptat. Deoarece, dacă nu se insistă ca eticheta să fie întotdeauna atribuită, va trebui să definim o etichetă implicită pentru orice funcție dată, precum și să evidențiem etichetele autorului, ceea ce va necesita din nou coordonare globală.)

Pe măsură ce volumul bazei de cunoștințe pentru funcțiile Wolfram crește, una dintre problemele care vor apărea cu siguranță este descoperirea funcțiilor, pentru care sistemul prevede o funcție de căutare (iar fișierele de definiție pot include cuvinte cheie etc.). Pentru funcțiile încorporate în limbajul Wolfram, documentația conține toate tipurile de referințe transversale care ajută la „promovarea” funcțiilor. Funcțiile din depozitul de funcții pot face referire la funcțiile încorporate. Dar cum rămâne cu inversul? În acest sens, intenționăm să experimentăm cu diferite scheme pentru a prezenta funcțiile depozitului pe paginile de documentație pentru funcțiile încorporate.

Pentru funcțiile încorporate în limbajul Wolfram, există așa-numitul nivel de descoperire, asigurat de rețeaua de „pagini de referință”, care oferă liste organizate de funcții legate de domenii specifice. Este întotdeauna dificil să echilibrezi corect paginile unui ghid și, pe măsură ce limbajul Wolfram crește, paginile ghidului trebuie, adesea, să fie reorganizate complet. Este relativ simplu să plasezi funcții dintr-un depozit în categorii largi și chiar să descompui aceste categorii, dar este mult mai valoros să ai pagini de ghid organizate corect pentru limbaj. Până acum, nu este clar cum să le creăm cel mai bine pentru întreaga bază de cunoștințe a funcțiilor. De exemplu, CreateResourceObjectGallery în depozitul de funcții, oricine poate publica o pagină web care conține „selecțiile” sale din depozit:

Wolfram Function Repository: acces deschis la o platformă pentru extensiile limbajului Wolfram

Depozitul de funcții Wolfram este configurat ca un depozit permanent de funcții, unde orice funcție va funcționa întotdeauna. Fără îndoială, pot apărea versiuni noi ale funcțiilor și ne așteptăm ca unele funcții să devină, în timp, învechite. Funcțiile vor funcționa dacă sunt utilizate în programe, dar paginile lor de documentație vor face referire la funcții noi, mai avansate.

Depozitul de funcții Wolfram este destinat obținerii rapide de noi funcții și explorării noilor capabilități ale limbajului Wolfram. Cu un grad ridicat de optimism, sperăm că o parte din ceea ce a fost explorat în depozitul de funcții va avea sens să devină părți integrate ale limbajului principal Wolfram Language. În ultima decadă, am avut un set similar de funcții care au fost prezentate inițial în Wolfram | Alpha. Și una dintre lecțiile învățate din această experiență este că pentru a atinge standardele de calitate și coerență asupra căror punem accent în tot ce este integrat în limbajul Wolfram, este nevoie de multă muncă, care este, de cele mai multe ori, mai complexă decât eforturile inițiale de implementare a ideii. Dar, chiar și așa, o funcție în baza de cunoștințe a funcțiilor poate servi drept dovadă foarte utilă a conceptului unei funcții viitoare, care în cele din urmă ar putea fi integrată în limbajul Wolfram.

Aici, cel mai important lucru este că funcția din depozitul de funcții este disponibilă pentru fiecare utilizator pt. utilizare imediată. Este posibil ca funcția încorporată a limbajului să fie mult mai bună și mai performantă, dar depozitul de funcții va permite utilizatorilor să aibă acces imediat la toate noile funcții. Și, ceea ce este deosebit de important, această idee permite fiecăruia să adauge funcții noi conforme dorințelor sale.

În trecut, această idee în istoria limbajului Wolfram nu ar fi funcționat la fel de bine ca acum, dar în această etapă limbajul are deja atât de mult efort investit și o înțelegere atât de profundă a principiilor de design, încât acum pare foarte posibil ca o mare comunitate de utilizatori să adauge funcții care să susțină coerența proiectului, astfel încât să fie utile pentru un public larg.

În comunitatea utilizatorilor Limbajului Wolfram există un spirit incredibil de talent. (Desigur, această comunitate include mulți dintre cei mai de seamă specialiști în cercetare și dezvoltare din cele mai diverse domenii.) Sper că depozitul de funcții Wolfram va oferi o platformă eficientă pentru explorarea și răspândirea acestui spirit de talent. Numai împreună putem crea ceva ce va extinde semnificativ domeniul în care paradigma computațională a limbajului Wolfram poate fi aplicată.

În cei peste 30 de ani, am parcurge un drum lung cu limbajul Wolfram. Acum, împreună, să mergem și mai departe. Îndemn cu căldură toți utilizatorii respectați ai limbajului Wolfram din întreaga lume să utilizeze depozitul funcțional ca platformă și un nou proiect software precum Free Wolfram Engine pentru dezvoltatori.

Sursa: habr.com

Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS 🔥 Cumpără un hosting fiabil pentru site-uri cu protecție DDoS, servere VPS VDS | ProHoster