Is there a reason why swift package type isn't executable by default?

One of the pillars of swift is progressive disclosure but it seems the opposite of it applies when creating packages.

When someone tries to make their first, simplest, hello world package, would probably use the simplest command

swift package init

Unfortunately it doesn't do what you want, because the default type is library. It's useless at this point and greets you with error: no executable product available. Now user needs to learn about products, package types, dependencies and stuff, to even use what they just created.

Wouldn't it be better for it to have an executable type by default, and greet the user with a nice Hello, world!, and leave all the learning for later? Is there a reason why library was chosen as a default?

And if there is no reason, can I simply do a pull request with that change without going through Swift evolution?

4 Likes

SPM is a tool for package management other than project initializer. Why would we need another tool to create Xcode project?

I'm not trying to remove any options, just change what is the default when creating new package :)

swift package generate-xcodeproj is a separate command, unrelated to what I would like to change

There is already swift package --type executable for creating a package in the way you're describing.

Library packages are the default because the assumption is that library products are more common than executable products.

2 Likes

Ah, that's unfortunate, especially because I make a lot more executable packages than libraries

2 Likes

I’ll preface this by saying I have no concrete evidence to back this up, this is just an unsubstantiated claim based on my limited personal experience: I think this is intentional, to encourage the functionality of your package to be separate from how it’s invoked. While I also find myself writing more executables than libraries, more often than not I also find it useful to have the core model of my executable in a library and then produce command-line bindings as an executable for it. This means that I can then reuse the code in a separate project directly through Swift Package Manager instead of needing to go split out code later or call the end executable as a sub-process (which incurs a pretty big performance hit).

So, by setting the default package type to library it feels like a gentle nudge in that direction from the beginning, to promote code reuse.

1 Like