Shepherd is a wonderful little service manager. The project has been integrating the good features of systemd (socket activation, timers, etc.) while retaining the hackability of using a fully featured programming language for configuration. Been happily using it with Guix for over a decade!
Also a note since there are a number of comments on here about this being a rival for Systemd: Shepherd precedes Systemd by quite a bit! Shepherd was previously known as "dmd", the "daemon for managing daemons", which was made in 2003! So in that sense, if anything was imitating anything (and not claiming anything was), it would be the reverse :)
You've been using Guix for over a decade? Is there somewhere I can read more about your experience? I think Guix is a cooler version of nix but I've been put off by the lack of packages and smaller community.
Not OP, but I've been daily driving Guix for about 5 years now quite happily. The biggest paint point with vanilla Guix is probably a lack of non-libre packages, especially the linux-libre kernel which strips out blobs. However, the nonguix [1] channel handily fills that hole, and there is first-class support for running a Nix daemon service [0] to cover anything not in nonguix.
Guix documentation is top notch, and it's really nice having all that available locally as texinfo pages. For writing packages yourself, I've found the Guix source to be eminently more greppable than Nix, which eases the dev onramp.
Nix's daemon is definitely more performant than Guix's, so equivalent operations will usually be quite a bit slower in Guix, but on the whole I'd say that Guix's more cohesive design makes the system more pleasant to work with.
(I know I could just RTFM but since you offered!) Does it do something like NixOS for declaring modules as functions and resolving the configuration as a fixed point of all module function applications (roughly, I don't think I'm describing it well)? This is a beautifully elegant way of defining configuration-with-options using lazy evaluation but it often leads to headaches like infinite recursion. Since Guile is not a lazy language I wonder how it achieves this.
I don’t know how Guile does this, but note that finding a fixed point does not generally require a lazy language; you just can’t do it naively — you can still take a bunch of functions that act on a config and ‘while (changing) keep applying’ — equivalently, the Y combinator can’t be evaluated strictly to get your fixed points, but the Z combinator can.
In all honesty, I don't know what that means, but the way Guix does configuration is with the Lisp equivalent of a builder pattern, which ends up looking quite like a key-value store.
(foo-configuration
(bar-property baz-value)
...)
> Shepherd is a wonderful little service manager
I believe you
But what practical use is it?
I cannot tell.
> practical use
service manager.
Where by you can create a service of your own application in userland without needing to be PID 1 to execute the service. With all the bells and whistles of monitoring and trigger.
Eh, I'd say systemd still has far better dmcrypt support. The bad (I used to think it was terrible, but I tried installing Debian today, which lowered the bar even further) support for full-disk encryption is what keeps me off Guix, as a matter of fact.
okay
Taking a quick look at this, the first thing I notice is that the configuration file syntax is obtuse and nigh-illegible unless you already know what things are, and even then it's cumbersome and looks frustrating to write.
They say you don't need to be an expert on guile scheme to build a service file, but it does seem as though you need to know things like what `'(ntpd)` means, which I assumed was some kind of identifier literal, and it seems to be what's called a 'data literal' in scheme, but I had to google to discover that since the actual guile scheme documentation didn't seem to explain that syntax at all.
I get that there are benefits to being able to do more advanced scripting in a service file, but this seems like a classic example of programmers writing things for programmers and not for users (or at least, not for users who don't 'get it').
Going to chalk this up as another 'GNU reimplemented something badly because of NIH syndrome' incident and move on.
I think this may be just due to unfamiliarity. Like, if that mess you shared was written as follows:
this wouldn't bat an eye. Even though I've never used Guile, just familiarity with Elisp makes that example pretty straightforward. Lisp-adjacent people would all pretty quickly grok this I presume.
And I think it's also hard to claim that one is better than the other. I personally have gotten my feet wet with Guix and I would love the time to become more familiar it.
I would definitely bat an eye at "make fork exec constructor", regardless of what syntax sugar you sprinkle on that abomination.
While I agree it's hard to claim one is outright better than the other and there are a lot of factors that go into it, I do feel it's important to toss my chip in as someone who's not familiar with Lisp, Scheme, or any other functional language that I find it's syntax and layout particularly difficult to parse, let alone get started with compared to say, the INI-inspired systemd conf files. I can detail why but the mere fact that I'd have to learn an entire functional programming language (no matter how "easy/simple" it's claimed to be) to be able to competently edit a service file is a huge immediate turn-off for me.
This is very basic Scheme syntax (plus Guile's keyword argument extension), nothing advanced and definitely not all of Scheme.
I don’t think this is about lisp syntax.
The systemd variant uses one of the universal DSLs for key-value pairs (key=value) and the universal DSL for calling programs (program name, space separated list of arguments).
The latter is even the same syntax that lisp uses for functions calls – thus I would argue the systemd config file looks more like a lisp program than the Guix version does.
As a person that has seen a reasonable amount of sexpression, this is what I would not bat an eye at:
It is also strictly less powerful because of that, often needing to launch bash scripts instead of the programs directly.
I understand this as systemds config being less powerful than using Guile?
If so, I fully agree, on the config being less powerful.
Maybe let me add to my original argument, because it does not seem to make it’s point well.
I think that it would be feasible (and worthwhile) to simplify the configuration structure while keeping Guile syntax, and have the complaint be a non issue.
As opposed to keeping the semantic structure and just changing the syntax as the comment I replied to proposed.
> and the universal DSL for calling programs (program name, space separated list of arguments).
Yeah, don't do that. Both the program name, and the arguments can and do contain spaces. Do instead what every other languages do, that is, use a list of strings to invoke programs.
> The latter is even the same syntax that lisp uses for functions calls
No it's not.
The way that this syntax (see bash, zsh, fish, etc) usually work is that these lists are separated by spaces. You can still quote arguments if they contain spaces (or escape the spaces).
Choosing space for a very common thing in your language often makes sense, as you reduce the amount of visual elements. Thus space is often used to apply arguments to functions. Lisp and Haskell are common examples Though, you could argue that in Lisp it only is an application if it is within parenthesis.
> The way that this syntax (see bash, zsh, fish, etc) usually work is that these lists are separated by spaces.
And programming languages that have variables, string type, and function calls do the opposite. In C, Python, JavaScript etc, in order to start a program you make a function call with a list of strings.
> Choosing space for a very common thing in your language often makes sense,
Not interpreting space separated things as strings but as keywords (built ins, variable names, literals) makes more sense for bigger programs.
Lisp looks like it uses spaces, but that's only when we look at certain kinds of tokens that are terminated by whitespace, like numbers and symbols.
So (ls -l .foo) is a three element list of symbols in Common Lisp or Scheme, sure.
Symbols are not strings though; we don't necessarily want to use symbols this way. For one thing, they get interned. That means they stick around forever, or until explicitly uninterned. The symbols are memorized so that the next time they appear, the same object is returned (almost always implemented as a pointer to the same symbol).
String tokens use mandatory double quotes: ("ls" "-l" ".foo")
Eh, I'm a Schemer (not Guile though) but the above is dramatically less readable and, at a glance, understandable than the equivalent systemd .target file. The problem with Lisps (but especially Schemes) is there's magic everywhere that makes no sense without having a sizeable context of the program you're working in.
IMO in this example there seems too be to little magic.
I vaguely learned lisp years ago and i already prefer the guile scheme over systemd - guile correctly takes an argument vector instead of a command string which needs to be split using some obtuse shell quoting rules.
Having the shell taken out of the equation is what Lennart promised but never delivered.
Interesting take. As a hobbyist, I get special characters and escapes wrong in systemd all the time, because they try to look like regular shell but aren't. And systemd-escape (or whatever it's called) just makes an ugly mess that makes it hard for me to read.
I don't know lisp, but the idea of having each argument be part of a list (kind of like launchd's xml format) resonates with me.
> the actual guile scheme documentation didn't seem to explain that syntax at all.
(quote data)
'data
Quoting is used to obtain a literal symbol (instead of a variable reference), a literal list (instead of a function call), or a literal vector. ' is simply a shorthand for a quote form. For example,
It's a basic concept of Lisp. Everything is evaluated, unless quoted. Code is data is code!
> Code is data is code!
Which nowadays is 'yaml is code is yaml is code is yaml' in the devops world. The wheel turns.
I tell ya, it was sometimes difficult to be a lisp guy doing devops full-time.
...only with more parsing gotchas :(
I agree systemd's is easier to understand, and I'm a happy systemd user.
But some of Shepherd's strengths are in other examples, and it makes sense to evaluate the whole.
A few examples:
* if we want multiple similar services, I'd prefer writing a Guile function than using systemd templates.
* the above Shepherd guile code lives lexically alongside your wider Guix guile code. AST-aware syntax highlighting and refactoring tools would treat them the same. That's pretty neat and beats having two different languages. Guix calls this g-expressions.
This "one language for all your system" is pretty compelling, but Guix's feature set is a bit too far behind NixOS at the moment for me.
> NIH syndrome
I would be using nonGuix if it booted on my machine (libre seemingly has its claws too deep), instead of Nix, precisely because Guix has far less NIH: Nix is homegrown everything. Guile was a pre-existing project (for both Guix and The Shepherd), for a pre-existing language family.
If you ever want to return to it, the nonguix ISO can be notoriously buggy. A better approach is to use the normal Guix ISO with an ethernet cable during installation and while setting up nonguix and your drivers.
i don't have access to an ethernet cable
The system is integrated into Guix, so makes sense to use s-exp for the configuration.
Systemd has done things that previously were trivial very difficult. I would like to know how it fares in that arena. The syntax can just be learned.
Why do we use the list function, when all the arguments are literal string objects? That wants to be a quoted literal list like this:
Why isn't the configuration language mainly declarative, with executable Scheme only available other escape hatch to use as an exception rather than the rule?
I don't want to worry about list versus quote in a configuration language, because they shouldn't be evaluation going on, or not by default.
Guile has been the scripting language of choice for GNU before the Internet was called Internet. It hasn't even been disliked, it's been simply ignored, for the most part.
I know that's true, having heard it talked about a lot over the years. But why, though? What is it about Guile that made GNU pick it over CL or Scheme (or TCL or Lua or...)?
NM, answered my own question. It’s literally Scheme.
> TCL
I actually know the answer to that one!
> The principal lesson of Emacs is that a language for extensions should not be a mere "extension language". It should be a real programming language, designed for writing and maintaining substantial programs. Because people will want to do that!
> Another lesson from Emacs is that the way to make sure an extension facility is really flexible is to use it to write a large portion of the ordinary released system. If you try to do that with Tcl, you will encounter its limitations.
> Tcl was not designed to be a serious programming language. It was designed to be a "scripting language", on the assumption that a "scripting language" need not try to be a real programming language. So Tcl doesn't have the capabilities of one. It lacks arrays; it lacks structures from which you can make linked lists. It fakes having numbers, which works, but has to be slow.
From Why you should not use Tcl by Richard Stallman [1].
Brilliant. That's exactly the kind of information I was missing. I don't know enough about Tcl to opine on whether he was right, but if that's what RMS thought about it, I can see why he'd push back hard against it..
Guile is an implementation of Scheme. As for why not CL, Stallman has expressed his dislike for CL, especially as a scripting language a lot of times over the years. Which is pretty funny because a lot of the criticisms he has about it (like the namespace system and keyword arguments) are in Guile now.
I mean, they're pretty much the same right? You can't abstract away the services and you need to pass arguments to the executable (ntpd in this case).
I don't see more or fewer issues, but I also don't see the value to using Scheme instead of a conf. file like format.
At the end, there's talk about adding the possibility to live reconfigure services, which is pretty cool but I don't really see what kind of users are targeted by that use-case, at least not regular users like me who's running Linux on a single laptop.
The link at the end (https://spritely.institute/news/spritely-nlnet-grants-decemb...) is IMO much more interesting since it would make it possible to orchestrate several machines and their services as well. If you have live reloading as well, I think it would make for good developer experience.
My main gripe with Guile is its ergonomics and tooling: no LSP, no linter, no step-debugger that I know of and the docs are often unhelpful imo.
Maybe I'm not Scheme brained enough but I think it's a shame because there are some really cool projects out there (anything https://spritely.institute/ really).
P.S: I know that some people will tell me to get used to REPL based development which I think is fine for small-ish projects but I can't understand the flow one uses for larger projects where many components might need to talk to each other.
To be fair the Guile one is properly quoted and specifies the log file. make-forkexec-constructor is a really terrible name though, and Guile is a poor choice.
[deleted]
For those that don't know, GNU Shepherd is an init system (like systemd) written in Guile (a LISP), the unit files are written with Guile too.
My main remark is: please do consider DESKTOP more than HPC etc, Guix System have a great potential to surpass NixOS for good but can't until the desktop will be the main driver, because before working on a system we enjoy it personally, and personally means desktops and homeservers...
That’s actually a pretty badass name for an init system.
"give a man an inch and they'll take a mile" and what not, but,
It would be neat to have some real management APIs for the things running on a page, to be able to manage long running processes & workers.
A bit more niche than for general webapps, but systemgo comes to mind; a re-impl of some of systemd in go, specifically designed to be run on the web in Browsix.
https://github.com/plasma-umass/systemgo
Amusingly enough, the main direction Shepherd is exploring right now is integrating Spritely Goblins (the folks that are also writing Hoot), so that it would have a distributed, capability-based process manager. I wouldn't say running Shepherd with Hoot is a direct goal of this, but it may fall out naturally from it.
Shepherd may actually work in Hoot right now -- I know the Spritely team were working on getting Guile's fibers library to work in WASM, and that's probably the biggest lift.
It may be possible to get Shepherd to work with Hoot eventually! I'm not sure what on earth it would mean though. What daemons would you manage in the browser? But it's indeed a fun idea!
If you could configure a fleet of machines from a browser window, over the network; that would be pretty cool. No clue how that would work in practice here though.
Since everything would be speaking OCapN you could use the browser interface as a convenient command center. This idea is becoming quite appealing to me actually... would be cool to have a little dashboard showing the health of my servers and be able to restart a failed service if I needed to.
It would be interesting, though I don't know if it would make sense. In any case, the way to do it would be to extract all the code that does POSIX things into an abstraction layer. Shepherd is built on the Fibers async system which Hoot supports so that part shouldn't be an issue.
Shepherd is a wonderful little service manager. The project has been integrating the good features of systemd (socket activation, timers, etc.) while retaining the hackability of using a fully featured programming language for configuration. Been happily using it with Guix for over a decade!
NLnet has funded a really cool project to turn Shepherd into a distributed system that enables a fleet of Shepherds to cooperate. https://nlnet.nl/project/DistributedShepherd/
Also a note since there are a number of comments on here about this being a rival for Systemd: Shepherd precedes Systemd by quite a bit! Shepherd was previously known as "dmd", the "daemon for managing daemons", which was made in 2003! So in that sense, if anything was imitating anything (and not claiming anything was), it would be the reverse :)
You've been using Guix for over a decade? Is there somewhere I can read more about your experience? I think Guix is a cooler version of nix but I've been put off by the lack of packages and smaller community.
Not OP, but I've been daily driving Guix for about 5 years now quite happily. The biggest paint point with vanilla Guix is probably a lack of non-libre packages, especially the linux-libre kernel which strips out blobs. However, the nonguix [1] channel handily fills that hole, and there is first-class support for running a Nix daemon service [0] to cover anything not in nonguix.
Guix documentation is top notch, and it's really nice having all that available locally as texinfo pages. For writing packages yourself, I've found the Guix source to be eminently more greppable than Nix, which eases the dev onramp.
Nix's daemon is definitely more performant than Guix's, so equivalent operations will usually be quite a bit slower in Guix, but on the whole I'd say that Guix's more cohesive design makes the system more pleasant to work with.
Happy to help if you have any specific questions!
[0] https://guix.gnu.org/manual/en/guix.html#Nix-service
[1] https://gitlab.com/nonguix/nonguix/
(I know I could just RTFM but since you offered!) Does it do something like NixOS for declaring modules as functions and resolving the configuration as a fixed point of all module function applications (roughly, I don't think I'm describing it well)? This is a beautifully elegant way of defining configuration-with-options using lazy evaluation but it often leads to headaches like infinite recursion. Since Guile is not a lazy language I wonder how it achieves this.
I don’t know how Guile does this, but note that finding a fixed point does not generally require a lazy language; you just can’t do it naively — you can still take a bunch of functions that act on a config and ‘while (changing) keep applying’ — equivalently, the Y combinator can’t be evaluated strictly to get your fixed points, but the Z combinator can.
In all honesty, I don't know what that means, but the way Guix does configuration is with the Lisp equivalent of a builder pattern, which ends up looking quite like a key-value store.
(foo-configuration (bar-property baz-value) ...)
> Shepherd is a wonderful little service manager
I believe you
But what practical use is it?
I cannot tell.
> practical use
service manager.
Where by you can create a service of your own application in userland without needing to be PID 1 to execute the service. With all the bells and whistles of monitoring and trigger.
Eh, I'd say systemd still has far better dmcrypt support. The bad (I used to think it was terrible, but I tried installing Debian today, which lowered the bar even further) support for full-disk encryption is what keeps me off Guix, as a matter of fact.
okay
Taking a quick look at this, the first thing I notice is that the configuration file syntax is obtuse and nigh-illegible unless you already know what things are, and even then it's cumbersome and looks frustrating to write.
e.g. instead of systemd's simple:
We have this mess: They say you don't need to be an expert on guile scheme to build a service file, but it does seem as though you need to know things like what `'(ntpd)` means, which I assumed was some kind of identifier literal, and it seems to be what's called a 'data literal' in scheme, but I had to google to discover that since the actual guile scheme documentation didn't seem to explain that syntax at all.I get that there are benefits to being able to do more advanced scripting in a service file, but this seems like a classic example of programmers writing things for programmers and not for users (or at least, not for users who don't 'get it').
Going to chalk this up as another 'GNU reimplemented something badly because of NIH syndrome' incident and move on.
I think this may be just due to unfamiliarity. Like, if that mess you shared was written as follows:
this wouldn't bat an eye. Even though I've never used Guile, just familiarity with Elisp makes that example pretty straightforward. Lisp-adjacent people would all pretty quickly grok this I presume.And I think it's also hard to claim that one is better than the other. I personally have gotten my feet wet with Guix and I would love the time to become more familiar it.
I would definitely bat an eye at "make fork exec constructor", regardless of what syntax sugar you sprinkle on that abomination.
While I agree it's hard to claim one is outright better than the other and there are a lot of factors that go into it, I do feel it's important to toss my chip in as someone who's not familiar with Lisp, Scheme, or any other functional language that I find it's syntax and layout particularly difficult to parse, let alone get started with compared to say, the INI-inspired systemd conf files. I can detail why but the mere fact that I'd have to learn an entire functional programming language (no matter how "easy/simple" it's claimed to be) to be able to competently edit a service file is a huge immediate turn-off for me.
This is very basic Scheme syntax (plus Guile's keyword argument extension), nothing advanced and definitely not all of Scheme.
I don’t think this is about lisp syntax.
The systemd variant uses one of the universal DSLs for key-value pairs (key=value) and the universal DSL for calling programs (program name, space separated list of arguments).
The latter is even the same syntax that lisp uses for functions calls – thus I would argue the systemd config file looks more like a lisp program than the Guix version does.
As a person that has seen a reasonable amount of sexpression, this is what I would not bat an eye at:
(start /path/to/ntpd -n -c /etc/ntpd.conf -u ntpd -g)
It is also strictly less powerful because of that, often needing to launch bash scripts instead of the programs directly.
I understand this as systemds config being less powerful than using Guile?
If so, I fully agree, on the config being less powerful.
Maybe let me add to my original argument, because it does not seem to make it’s point well.
I think that it would be feasible (and worthwhile) to simplify the configuration structure while keeping Guile syntax, and have the complaint be a non issue. As opposed to keeping the semantic structure and just changing the syntax as the comment I replied to proposed.
> and the universal DSL for calling programs (program name, space separated list of arguments).
Yeah, don't do that. Both the program name, and the arguments can and do contain spaces. Do instead what every other languages do, that is, use a list of strings to invoke programs.
> The latter is even the same syntax that lisp uses for functions calls
No it's not.
The way that this syntax (see bash, zsh, fish, etc) usually work is that these lists are separated by spaces. You can still quote arguments if they contain spaces (or escape the spaces).
Choosing space for a very common thing in your language often makes sense, as you reduce the amount of visual elements. Thus space is often used to apply arguments to functions. Lisp and Haskell are common examples Though, you could argue that in Lisp it only is an application if it is within parenthesis.
> The way that this syntax (see bash, zsh, fish, etc) usually work is that these lists are separated by spaces.
And programming languages that have variables, string type, and function calls do the opposite. In C, Python, JavaScript etc, in order to start a program you make a function call with a list of strings.
> Choosing space for a very common thing in your language often makes sense,
Not interpreting space separated things as strings but as keywords (built ins, variable names, literals) makes more sense for bigger programs.
Lisp looks like it uses spaces, but that's only when we look at certain kinds of tokens that are terminated by whitespace, like numbers and symbols.
So (ls -l .foo) is a three element list of symbols in Common Lisp or Scheme, sure.
Symbols are not strings though; we don't necessarily want to use symbols this way. For one thing, they get interned. That means they stick around forever, or until explicitly uninterned. The symbols are memorized so that the next time they appear, the same object is returned (almost always implemented as a pointer to the same symbol).
String tokens use mandatory double quotes: ("ls" "-l" ".foo")
Eh, I'm a Schemer (not Guile though) but the above is dramatically less readable and, at a glance, understandable than the equivalent systemd .target file. The problem with Lisps (but especially Schemes) is there's magic everywhere that makes no sense without having a sizeable context of the program you're working in.
IMO in this example there seems too be to little magic.
I vaguely learned lisp years ago and i already prefer the guile scheme over systemd - guile correctly takes an argument vector instead of a command string which needs to be split using some obtuse shell quoting rules.
Having the shell taken out of the equation is what Lennart promised but never delivered.
Interesting take. As a hobbyist, I get special characters and escapes wrong in systemd all the time, because they try to look like regular shell but aren't. And systemd-escape (or whatever it's called) just makes an ugly mess that makes it hard for me to read.
I don't know lisp, but the idea of having each argument be part of a list (kind of like launchd's xml format) resonates with me.
> the actual guile scheme documentation didn't seem to explain that syntax at all.
Quoting is used to obtain a literal symbol (instead of a variable reference), a literal list (instead of a function call), or a literal vector. ' is simply a shorthand for a quote form. For example, Note that an application must not attempt to modify literal lists or vectors obtained from a quote form, since they may be in read-only memory.— <https://www.gnu.org/software/guile/manual/html_node/Expressi...>
You don't have to be an expert, but knowing the basics of Lisp helps. The full definition of the example "ntpd" service is clear to read.
> the actual guile scheme documentation didn't seem to explain that syntax at all
It does, here: https://www.gnu.org/software/guile/manual/html_node/Expressi...
It's a basic concept of Lisp. Everything is evaluated, unless quoted. Code is data is code!
> Code is data is code!
Which nowadays is 'yaml is code is yaml is code is yaml' in the devops world. The wheel turns.
I tell ya, it was sometimes difficult to be a lisp guy doing devops full-time.
...only with more parsing gotchas :(
I agree systemd's is easier to understand, and I'm a happy systemd user.
But some of Shepherd's strengths are in other examples, and it makes sense to evaluate the whole.
A few examples:
* if we want multiple similar services, I'd prefer writing a Guile function than using systemd templates.
* the above Shepherd guile code lives lexically alongside your wider Guix guile code. AST-aware syntax highlighting and refactoring tools would treat them the same. That's pretty neat and beats having two different languages. Guix calls this g-expressions.
This "one language for all your system" is pretty compelling, but Guix's feature set is a bit too far behind NixOS at the moment for me.
> NIH syndrome
I would be using nonGuix if it booted on my machine (libre seemingly has its claws too deep), instead of Nix, precisely because Guix has far less NIH: Nix is homegrown everything. Guile was a pre-existing project (for both Guix and The Shepherd), for a pre-existing language family.
If you ever want to return to it, the nonguix ISO can be notoriously buggy. A better approach is to use the normal Guix ISO with an ethernet cable during installation and while setting up nonguix and your drivers.
i don't have access to an ethernet cable
The system is integrated into Guix, so makes sense to use s-exp for the configuration.
Systemd has done things that previously were trivial very difficult. I would like to know how it fares in that arena. The syntax can just be learned.
Why do we use the list function, when all the arguments are literal string objects? That wants to be a quoted literal list like this:
Why isn't the configuration language mainly declarative, with executable Scheme only available other escape hatch to use as an exception rather than the rule?I don't want to worry about list versus quote in a configuration language, because they shouldn't be evaluation going on, or not by default.
Guile has been the scripting language of choice for GNU before the Internet was called Internet. It hasn't even been disliked, it's been simply ignored, for the most part.
I know that's true, having heard it talked about a lot over the years. But why, though? What is it about Guile that made GNU pick it over CL or Scheme (or TCL or Lua or...)?
NM, answered my own question. It’s literally Scheme.
> TCL
I actually know the answer to that one!
> The principal lesson of Emacs is that a language for extensions should not be a mere "extension language". It should be a real programming language, designed for writing and maintaining substantial programs. Because people will want to do that!
> Another lesson from Emacs is that the way to make sure an extension facility is really flexible is to use it to write a large portion of the ordinary released system. If you try to do that with Tcl, you will encounter its limitations.
> Tcl was not designed to be a serious programming language. It was designed to be a "scripting language", on the assumption that a "scripting language" need not try to be a real programming language. So Tcl doesn't have the capabilities of one. It lacks arrays; it lacks structures from which you can make linked lists. It fakes having numbers, which works, but has to be slow.
From Why you should not use Tcl by Richard Stallman [1].
[1] https://vanderburg.org/old_pages/Tcl/war/0000.html
Brilliant. That's exactly the kind of information I was missing. I don't know enough about Tcl to opine on whether he was right, but if that's what RMS thought about it, I can see why he'd push back hard against it..
Guile is an implementation of Scheme. As for why not CL, Stallman has expressed his dislike for CL, especially as a scripting language a lot of times over the years. Which is pretty funny because a lot of the criticisms he has about it (like the namespace system and keyword arguments) are in Guile now.
I mean, they're pretty much the same right? You can't abstract away the services and you need to pass arguments to the executable (ntpd in this case).
I don't see more or fewer issues, but I also don't see the value to using Scheme instead of a conf. file like format.
At the end, there's talk about adding the possibility to live reconfigure services, which is pretty cool but I don't really see what kind of users are targeted by that use-case, at least not regular users like me who's running Linux on a single laptop.
The link at the end (https://spritely.institute/news/spritely-nlnet-grants-decemb...) is IMO much more interesting since it would make it possible to orchestrate several machines and their services as well. If you have live reloading as well, I think it would make for good developer experience.
My main gripe with Guile is its ergonomics and tooling: no LSP, no linter, no step-debugger that I know of and the docs are often unhelpful imo.
Maybe I'm not Scheme brained enough but I think it's a shame because there are some really cool projects out there (anything https://spritely.institute/ really).
P.S: I know that some people will tell me to get used to REPL based development which I think is fine for small-ish projects but I can't understand the flow one uses for larger projects where many components might need to talk to each other.
To be fair the Guile one is properly quoted and specifies the log file. make-forkexec-constructor is a really terrible name though, and Guile is a poor choice.
For those that don't know, GNU Shepherd is an init system (like systemd) written in Guile (a LISP), the unit files are written with Guile too.
My main remark is: please do consider DESKTOP more than HPC etc, Guix System have a great potential to surpass NixOS for good but can't until the desktop will be the main driver, because before working on a system we enjoy it personally, and personally means desktops and homeservers...
That’s actually a pretty badass name for an init system.
"give a man an inch and they'll take a mile" and what not, but,
I wonder how hard this would be to port to Hoot, a web assembly/wasm-ified Guile Scheme. https://spritely.institute/hoot/
It would be neat to have some real management APIs for the things running on a page, to be able to manage long running processes & workers.
A bit more niche than for general webapps, but systemgo comes to mind; a re-impl of some of systemd in go, specifically designed to be run on the web in Browsix. https://github.com/plasma-umass/systemgo
Amusingly enough, the main direction Shepherd is exploring right now is integrating Spritely Goblins (the folks that are also writing Hoot), so that it would have a distributed, capability-based process manager. I wouldn't say running Shepherd with Hoot is a direct goal of this, but it may fall out naturally from it.
Shepherd may actually work in Hoot right now -- I know the Spritely team were working on getting Guile's fibers library to work in WASM, and that's probably the biggest lift.
It may be possible to get Shepherd to work with Hoot eventually! I'm not sure what on earth it would mean though. What daemons would you manage in the browser? But it's indeed a fun idea!
If you could configure a fleet of machines from a browser window, over the network; that would be pretty cool. No clue how that would work in practice here though.
Since everything would be speaking OCapN you could use the browser interface as a convenient command center. This idea is becoming quite appealing to me actually... would be cool to have a little dashboard showing the health of my servers and be able to restart a failed service if I needed to.
Wow, that's a very fun reply! Nice.
Fingers crossed that the Stack Switching spec gets adopted & serves Guile Hoot's needs for fibers. https://github.com/WebAssembly/stack-switching
Stack switching in wasm would be great (as long as they aren't nerfed which they might be!) but note that Hoot has fibers right now: https://gitlab.com/spritely/guile-hoot/-/tree/main/lib/fiber...
> I wonder how hard this would be to port to Hoot
It would be interesting, though I don't know if it would make sense. In any case, the way to do it would be to extract all the code that does POSIX things into an abstraction layer. Shepherd is built on the Fibers async system which Hoot supports so that part shouldn't be an issue.