Ur (programmeringsspråk)
Paradigm | funktionell , reaktiv |
---|---|
Familj | ML |
Designad av | Adam Chlipala |
Dök först upp | december 2014 |
Stabil frisättning | 20200209 release / 9 februari 2020
|
Plattform | POSIX |
Licens | öppen källa |
Filnamnstillägg | .ur, .urs, .urp |
Hemsida | |
Influerad av | |
Haskell , ML |
Ur även kallad Ur/Web är ett gratis och öppen källkod funktionellt programmeringsspråk specifikt för webbutveckling , skapat av Adam Chlipala vid Massachusetts Institute of Technology som från ett enda program producerar serverkod , webbläsarklientkod och SQL -kod specifik för den valda databas backend .
Ur stöder en kraftfull typ av metaprogrammering baserad på radtyper.
Ur/Web är Ur plus ett speciellt standardbibliotek och tillhörande regler för analys och optimering. Ur/Web stöder konstruktion av dynamiska webbapplikationer med stöd av SQL- databaser. Signaturen för standardbiblioteket är sådan att välskrivna Ur/Web-program "inte går fel" i mycket vid mening. De kraschar inte bara under vissa sidgenerationer, men de kanske inte heller:
- Lider av alla typer av kodinjektionsattacker
- Returnera ogiltig HTML
- Innehåller döda intra-applikationslänkar
- Har missmatchningar mellan HTML-formulär och de fält som förväntas av deras hanterare
- Inkludera kod på klientsidan som gör felaktiga antaganden om tjänsterna i " AJAX "-stil som fjärrwebbservern tillhandahåller
- Försök med ogiltiga SQL- frågor
- Använd olämplig rangordning eller unmarshaling i kommunikation med SQL-databaser eller mellan webbläsare och webbservrar
Denna typ av säkerhet är bara grunden för Ur/Web-metoden. Det är också möjligt att använda metaprogrammering för att bygga betydande applikationsdelar genom analys av typstruktur.
Ur /Web- kompilatorn producerar också mycket effektiv objektkod som inte använder skräpinsamling .
Implementeringen av allt detta är öppen källkod .
SQL- syntaxmallar inbäddade i språket underlättar hanteringen av tabeller.
Även om syntaxen är baserad på Standard ML innehåller språket begrepp från Haskell med ytterligare typmanipulation.
Ajax samtal/svar serialiseras genom en monad som kallas transaktion (motsvarar Haskells IO) och dess rangering och avkodning är inkapslad i rpc -funktionen.
Webbläsarklienten inkluderar funktionella reaktiva programmeringsfaciliteter som använder typen (källa a)
och en signalmonad .
Ur/Web gör inte bara webbapplikationer lättare att skriva, det gör dem också säkrare.
"Låt oss säga att du vill ha en kalenderwidget på din webbsida, och du kommer att använda ett bibliotek som tillhandahåller kalenderwidgeten, och på samma sida finns det också en annonsruta som är baserad på kod som tillhandahålls av annonsnätverket ", sa Chlipala.
"Vad du inte vill är att annonsnätverket ska kunna ändra hur kalendern fungerar eller att författaren till kalenderkoden ska kunna störa leveransen av annonserna."
Exempel på program
Detta är ett demoprogram som visar klient-, server- och databaskod med Ajax- kommunikation, från webbdemos, med extra kommentarer för att beskriva var och en av komponenterna:
Gränssnittsfil ( ML -liknande signatur) med tillägget .urs:
(* miljömonaden kallas transaktion, motsvarar Haskells IO-monad *) val main : unit - > transaktionssida
Implementeringsfil (.ur-tillägg):
datatyplista t = Noll | _ Nackdelar med t * lista t tabell t : { Id : int , A : string } PRIMÄRNYCKEL - ID (* databasåtkomst på serversidan, anropad genom AJAX XmlHttpRequest inkapslad som ''rpc''-funktion (fjärrproceduranrop) *) fun add id s = (* sql dml-mall med {[uttryck]} *) dml ( INSERT INTO t ( Id , A ) VALUES ({[ id ]}, {[ s ]})) fun del id = dml ( DELETE FROM t WHERE t . Id = {[ id ]}) fun lookup id = (* haskell stil monadisk kod *) ro <- oneOrNoRows ( SELECT t . A FROM t WHERE t . Id = {[ id ]}); case ro av Inget => retur Inget (* return är ''monad'' lyftfunktion *) | Vissa r => return ( Vissa r . T . A ) (* ''check'' anropas av klientsidan onClick-händelsehanteraren, så det kommer att kompileras till JavaScript som inbäddat klientskript på sidan *) fun check ls = case ls of Noll => return () | Cons ( id , ls' ) => ao <- rpc ( lookup id ); (* Ajax-anrop till serversidan *) alert ( case ao of None => "Nada" | Some a => a ); check ls' fun main () = idAdd <- source "" ; aAdd <- source "" ; idDel <- source "" ; (* genererar webbsida med JavaScript-inneslutningar *) returnera <xml><body> <button value = "Kontrollera värden på 1, 2 och 3" onclick ={ fn _ => let val mylist = 1 :: 2 :: 3 :: [] in check mylist end } /><br/> <br/> <button value = "Add" onclick ={ fn _ => id <- get idAdd ; a <- get aAdd ; rpc ( lägg till ( readError id ) a ) (* Ajax-anrop till serversidan *) } /> <ctextbox source ={ idAdd } /> <ctextbox source ={ aAdd } /><br/> <br/> < knappvärde = "Delete" onclick ={ fn _ => id <- get idDel ; rpc ( del ( readError id )) (* Ajax-anrop till serversidan *) } /> <ctextbox source ={ idDel } /> </body></xml>
Projektfil (.urp-tillägg), måste innehålla en valfri direktivlista följt av en lista över projektmoduler:
# hash prefix rad kommentarer skriv om url Module1/main # ställ in root URL till Module1/main function exe myexename databas dbname=test # databasattribut. och parametrar sql noisy.sql
$/list # stdlib-moduler med prefixet "$/" modul2 # om den används av modul1 måste den föregå den modul1 # huvudmodul
- serversidan, sidhämtande funktioner utan biverkningar (http GET-metoden) är tillgängliga via en URL som /ModulePath/functionName; de ska ha typen (enhet -> transaktionssida) .
- För att exportera en sida som kan orsaka biverkningar, endast tillgänglig via HTTP POST, inkludera ett argument för sidhanteraren av typen Basis.postBody .
Sammanställa:
urweb module1 # letar efter module1.urp
Kör som en webbserver (andra lägen är CGI , FastCGI , ...):
./module1.exe -p 8081 # -h : Hjälp för RTS-alternativ
Bibliotek
- Det fördefinierade API:et
- Standardbiblioteket
- Per funktionstester
- Ur wiki - Bibliotek och FFI-bindningar
Specialfunktioner och problem
- Rekorduppdatering
datatyp mystruc k v = Tom | Nod för { Key : k , Value : v } fun setKey [ k ][ v ] (* typ polymorfism *) (_: ord k ) (* implicit förekomst av klass ord *) ( callerErrNote : string ) ( k1 : k ) ( my : mystruc k v ) : mystruc k v = om k1 < kmin då fel <xml>setKey : illegal k1 {[ callerErrNote ]} </xml> annat fall my of Node r => Node ( r -- #Key + + { Nyckel = k1 }) | _ => fel <xml>setKey : inte en nod {[ callerErrNote ]} </xml>
motsvarande signatur (snälla anteckningar (:::) implicit; (::) explicit):
con mystruc :: Typ -> Typ -> Typ (* tvåparameter typ konstruktor *) val setKey : k ::: Typ -> v ::: Typ -> ord k -> sträng -> k -> mystruc k v -> mystruc k v
- Rekordfält ellips
case my av Node { Key = k , ... } => doWhatever k | _ => ....
- Fel "Substitution i konstruktor är blockerad av en för djup enhetsvariabel"
Detta fel inträffar med typer av arity > 0 i kapslade fall eller let- satser och försvinner genom att typ kommentera variablerna i de kapslade satserna.
Se även
- Dark, ett programmeringsspråk för integrerad backend-utveckling
- Opa , ett programmeringsspråk för kombinerad frontend-backend-utveckling
- ^ UrWeb är ur beta
- ^ a b c d e f "Programmeringsspråkfamiljen Ur" . impredicative.com/ur . Hämtad 3 april 2016 .
- ^ Chlipala, Adam (januari 2015). "Ur/Web: En enkel modell för att programmera webben" . MIT / Association for Computing Machinery (ACM) . Hämtad 5 januari 2015 .
- ^ "Ta bort grymtandet av webbutveckling" . mit.edu. 23 december 2014 . Hämtad 29 december 2016 .
- ^ Ur språkdemoprogram
-
^
Chlipala, Adam (januari 2015). "Ur/Web Manual – Projektfiler" . https://enn.github.io/urweb-doc . Hämtad 8 januari 2015 .
{{ citera webben }}
: Extern länk i
( hjälp )|publisher=
- ^ Ur/webbhandboken - strukturen av webbapplikationer
- ^ Oväntat typfel: "Substitution i konstruktorn är blockerad av en för djup enhetsvariabel"