Solod is een nieuwe systeemtaal voor C- en Go-ontwikkelaars die bewust is ontworpen als een subset van de Go-taal. Door deze aanpak kan Solod profiteren van het rijke ecosysteem aan bestaande Go-tooling, zoals syntaxhighlighting, LSP's en pakketbeheersystemen.
De taal hergebruikt grote delen van de Go-standaardbibliotheek; sommige code is letterlijk overgenomen, terwijl andere delen zijn aangepast om handmatig geheugenbeheer met expliciete allocators te ondersteunen. Een cruciaal technisch kenmerk is dat alle Solod-code wordt vertaald naar C11 en vervolgens gecompileerd via GCC of Clang. Hierdoor is er geen runtime nodig en is de interoperabiliteit met C zeer efficiënt.
Hoewel standaard Go-tools niet alle beperkingen van de Solod-subset herkennen, wordt dit opgevangen door specifieke so tooling. De auteur stelt dat het hergebruiken van bewezen tools en bibliotheken een kracht is die de betrouwbaarheid en toegankelijkheid van de taal vergroot.
Leunen op Go
De tooling van Go
Solod is niet "Go-achtig" in de gebruikelijke zin, noch is het een poging om "de fouten van Go te herstellen". Op taalniveau is Solod letterlijk een subset van Go. Solod maakt veel gebruik van de bestaande tooling van Go, waaronder syntaxhighlighting, LSP, linters en het pakketbeheersysteem.
Neem bijvoorbeeld deze snelstartgids:
Snelstart
- Installeer de
so command-line tool:
``bash go install solod.dev/cmd/so@latest ``
- Maak een nieuw Go-project aan en voeg de Solod-dependency toe om de So-standaardbibliotheek te gebruiken:
``bash go mod init example go get solod.dev@latest ``
- Schrijf reguliere Go-code, maar gebruik Solod-pakketten in plaats van de standaard Go-pakketten:
```go package main import "solod.dev/so/math"
func main() { ans := math.Sqrt(1764) println("Hallo, wereld! Het antwoord is", int(ans)) } ```
- Voer het programma uit zonder het binary-bestand op te slaan:
``bash so run . ``
Dat is alles! Er is hier niets nieuws aan; het is grotendeels de standaard Go-workflow, met uitzondering van so run, wat een Go-programma is dat go run nabootst.
De standaardbibliotheek van Go
Solod hergebruikt ook veel code en tests uit de standaardbibliotheek van Go. Sommige delen zijn letterlijk overgenomen uit de broncode van Go, zoals deze twee stringfuncties:
// CutPrefix geeft s terug zonder het opgegeven voorvoegsel (prefix)
// en meldt of het voorvoegsel is gevonden.
func CutPrefix(s, prefix string) (string, bool) {
if !HasPrefix(s, prefix) {
return s, false
}
return s[len(prefix):], true
}
// HasPrefix meldt of de string s begint met het voorvoegsel.
func HasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
Natuurlijk behoudt Solod het auteursrecht van de Go-ontwikkelaars.
Sommige code vereist echter aanpassingen om handmatig geheugenbeheer met expliciete allocators te ondersteunen, zoals Solod dat gebruikt:
Go-versie:
func Clone(s string) string {
if len(s) == 0 {
return ""
}
b := make([]byte, len(s))
copy(b, s)
return unsafe.String(&b[0], len(b))
}
Solod-versie:
func Clone(a mem.Allocator, s string) string {
if len(s) == 0 {
return ""
}
b := mem.AllocSlice[byte](a, len(s), len(s))
copy(b, s)
return string(b)
}
De gelijkenis is hier duidelijk zichtbaar.
Een kanttekening
De Go-tools weten niet dat Solod een subset is van de volledige Go-taal, waardoor ze functies die Solod niet ondersteunt (zoals function literals of iteratoren) niet zullen markeren. Deze diagnostische meldingen komen van de aangepaste so tooling:
package main
func main() {
f := func(n int) {
println(n)
}
f(42)
}
main.go:4:7: function literals are not supported f := func(n int) { ^hier
Daarnaast betekent het feit dat een aanzienlijk deel van de standaardbibliotheek van Go letterlijk of met minimale wijzigingen is geporteerd, niet automatisch dat de code correct is. Solod heeft nog steeds eigen tests nodig, inclusief tests die draaien onder sanitizers en statische analyse-tools.
Uiteindelijk is alles C
Alle Solod-code wordt vertaald naar reguliere C11 en vervolgens gecompileerd met GCC of Clang. Solod leunt daarom net zoveel op C-tooling en decennia aan optimalisatiewerk als op die van Go.
Solod-code:
package main
import "solod.dev/so/math"
func main() {
// Wat zou het kunnen zijn?
ans := math.Sqrt(1764)
println("Hallo, wereld! Het antwoord is", int(ans))
}
Vertaalde C-code:
// -- main.h --
#pragma once
#include "so/builtin/builtin.h"
#include "so/math/math.h"
// -- main.c --
#include "main.h"
int main(void) {
// Wat zou het kunnen zijn?
double ans = math_Sqrt(1764.0);
so_println("%s %" PRIdINT, "Hallo, wereld! Het antwoord is", (so_int)(ans));
return 0;
}
De C-versie is uiteraard "luidruchtiger", zeker bij complexere programma's dan deze. Desondanks blijft het leesbaar. Omdat er geen runtime is, kost de interoperabiliteit tussen Solod en C niets.
Slotgedachten
Een nieuwe taal heeft niet noodzakelijkerwijs een nieuw ecosysteem nodig.
Solod leunt zwaar op Go, en ik zie dat als een kracht, niet als een zwakte. Het hergebruiken van bewezen tools en de standaardbibliotheek van Go maakt Solod betrouwbaarder en gemakkelijker in gebruik.
Leunen op Go
De tooling van Go
Solod is niet "Go-achtig" in de gebruikelijke zin, noch is het een poging om "de fouten van Go te herstellen". Op taalniveau is Solod letterlijk een subset van Go. Solod maakt veel gebruik van de bestaande tooling van Go, waaronder syntaxhighlighting, LSP, linters en het pakketbeheersysteem.
Neem bijvoorbeeld deze snelstartgids:
Snelstart
- Installeer de
so command-line tool:
``bash go install solod.dev/cmd/so@latest ``
- Maak een nieuw Go-project aan en voeg de Solod-dependency toe om de So-standaardbibliotheek te gebruiken:
``bash go mod init example go get solod.dev@latest ``
- Schrijf reguliere Go-code, maar gebruik Solod-pakketten in plaats van de standaard Go-pakketten:
```go package main import "solod.dev/so/math"
func main() { ans := math.Sqrt(1764) println("Hallo, wereld! Het antwoord is", int(ans)) } ```
- Voer het programma uit zonder het binary-bestand op te slaan:
``bash so run . ``
Dat is alles! Er is hier niets nieuws aan; het is grotendeels de standaard Go-workflow, met uitzondering van so run, wat een Go-programma is dat go run nabootst.
De standaardbibliotheek van Go
Solod hergebruikt ook veel code en tests uit de standaardbibliotheek van Go. Sommige delen zijn letterlijk overgenomen uit de broncode van Go, zoals deze twee stringfuncties:
// CutPrefix geeft s terug zonder het opgegeven voorvoegsel (prefix)
// en meldt of het voorvoegsel is gevonden.
func CutPrefix(s, prefix string) (string, bool) {
if !HasPrefix(s, prefix) {
return s, false
}
return s[len(prefix):], true
}
// HasPrefix meldt of de string s begint met het voorvoegsel.
func HasPrefix(s, prefix string) bool {
return len(s) >= len(prefix) && s[:len(prefix)] == prefix
}
Natuurlijk behoudt Solod het auteursrecht van de Go-ontwikkelaars.
Sommige code vereist echter aanpassingen om handmatig geheugenbeheer met expliciete allocators te ondersteunen, zoals Solod dat gebruikt:
Go-versie:
func Clone(s string) string {
if len(s) == 0 {
return ""
}
b := make([]byte, len(s))
copy(b, s)
return unsafe.String(&b[0], len(b))
}
Solod-versie:
func Clone(a mem.Allocator, s string) string {
if len(s) == 0 {
return ""
}
b := mem.AllocSlice[byte](a, len(s), len(s))
copy(b, s)
return string(b)
}
De gelijkenis is hier duidelijk zichtbaar.
Een kanttekening
De Go-tools weten niet dat Solod een subset is van de volledige Go-taal, waardoor ze functies die Solod niet ondersteunt (zoals function literals of iteratoren) niet zullen markeren. Deze diagnostische meldingen komen van de aangepaste so tooling:
package main
func main() {
f := func(n int) {
println(n)
}
f(42)
}
main.go:4:7: function literals are not supported f := func(n int) { ^hier
Daarnaast betekent het feit dat een aanzienlijk deel van de standaardbibliotheek van Go letterlijk of met minimale wijzigingen is geporteerd, niet automatisch dat de code correct is. Solod heeft nog steeds eigen tests nodig, inclusief tests die draaien onder sanitizers en statische analyse-tools.
Uiteindelijk is alles C
Alle Solod-code wordt vertaald naar reguliere C11 en vervolgens gecompileerd met GCC of Clang. Solod leunt daarom net zoveel op C-tooling en decennia aan optimalisatiewerk als op die van Go.
Solod-code:
package main
import "solod.dev/so/math"
func main() {
// Wat zou het kunnen zijn?
ans := math.Sqrt(1764)
println("Hallo, wereld! Het antwoord is", int(ans))
}
Vertaalde C-code:
// -- main.h --
#pragma once
#include "so/builtin/builtin.h"
#include "so/math/math.h"
// -- main.c --
#include "main.h"
int main(void) {
// Wat zou het kunnen zijn?
double ans = math_Sqrt(1764.0);
so_println("%s %" PRIdINT, "Hallo, wereld! Het antwoord is", (so_int)(ans));
return 0;
}
De C-versie is uiteraard "luidruchtiger", zeker bij complexere programma's dan deze. Desondanks blijft het leesbaar. Omdat er geen runtime is, kost de interoperabiliteit tussen Solod en C niets.
Slotgedachten
Een nieuwe taal heeft niet noodzakelijkerwijs een nieuw ecosysteem nodig.
Solod leunt zwaar op Go, en ik zie dat als een kracht, niet als een zwakte. Het hergebruiken van bewezen tools en de standaardbibliotheek van Go maakt Solod betrouwbaarder en gemakkelijker in gebruik.