Skip to content

propensive/soundness

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 

Repository files navigation

Soundness

Soundness is a loose collection of open-source libraries designed to take full advantage of new features of Scala 3 to write web and command-line applications, with a focus on lifting more operations to the type-level with safe and expressive syntax.

Soundness includes libraries for working with HTML, CSS, JSON, XML, CSV, typesafe strings, ANSI-escaped strings and Markdown, both calling HTTP and serving HTTP or the command line. Additionally, support for disk I/O, filewatching and the standard UNIX directory layout, environment variables, shell processes (including native keyboard interactivity), cryptographic functions, tabular output and regular expressions is provided, and includes representations of colors, directed acyclic graphs, multilingual strings, MIME types and generalized paths. Fundamental to these projects are utilities for generic derivation, checked interpolated strings, annotations, streaming operations, type providers library decoupling and unit testing with a WebDriver API for browser testing. A module also exists for Scala syntax highlighting. Everything builds upon minimal set of common tools.

Principles

Soundness embraces two core principles:

  1. Impossible states should be unrepresentable
  2. Transitions between states should be total

Together, these two principles eliminate an entire class of bugs.

More specifically, each library under the Soundness umbrella adheres to the following principles:

  • typesafe—taking full advantage of the Scala 3 typesystem
  • checked exceptions—but only if you choose to use them
  • safe literals—interpolated strings, checked at compiletime with Contextual
  • forbidden null—no method should ever return null, and no value should ever be null, guaranteed by the Scala typesystem
  • typeclasses—extensibility provided through Wisteria's generic derivation
  • immutability—mutation of state is avoided, even when working with streams
  • decoupled—modules use Anticipation to minimise unnecessary dependencies
  • functional programming—embracing the fundamentals of FP, but avoiding the complexity
  • small APIs—above all, code should be legible, natural and elegant

Typesafe

Scala 3's typesystem offers a rich variety of types for representing and combining constraints on values. This presents an opportunity to encode a value's invariants—facts about the value which we know will always be true—precisely in its type. These invariants then give us certainty that operations involving the value are safe. Or, that they're simply impossible. In general, this reduces the amount of branching, including exception handling, that's required in code. Extensive use of immutable datatypes adds further guarantees.

In particular, the type Text, an opaque type alias of String, is used in place of String at every opportunity. Text has a variety of useful methods, all of which are total functions or declare their exceptions. A String may always be converted to a Text with the show extension method, and a Text converted to a String by calling its method s.

Checked Exceptions

The latest release of Scala 3 introduces opt-in exception checking, and every Soundness method declares the exceptions it may throw in its signature. This makes it easy to write prototype code with a "let it fail" attitude and exception-checking off, and to migrate to production-quality code just by turning exception-checking on, and having the compiler require handlers for each exception—but without needing to transform types or switch to a monadic coding style.

Effectively, this transforms every partial function into a total function; when combined with the wise philosophy of making impossible states unrepresentable, exceptions become even more exceptional.

Forbidden null

The introduction of null into ALGOL was described by Tony Hoare as his "billion-dollar mistake", though it has persisted in numerous programming languages since. Scala 3 introduces new checks to help avoid null references, and Soundness projects take full advantage of these.

Safe Literals

When constructing a value, such as a JSON object or a URL, from a string literal, all the information is available at compiletime to check the validity of the string's contents. So, whenever possible, this is provided with interpolated strings, such as url"https://github.com/", using Contextual. Since checks are performed at compiletime, there is no risk of runtime exceptions arising from these values.

Typeclasses

The typeclass pattern, provided through contextual values (givens) is used extensively by Soundness libraries to provide ad-hoc polymorphism (in preference to subtype polymorphism). This not only allows user-defined types to participate naturally in all kinds of Soundness APIs, but also facilitates interaction between Soundness libraries and third-party libraries.

Decoupled

When working with libraries in different domains, it is common to need integration between them. For example, an HTTP server should be able to serve a XML value with the correct MIME type, without too much boilerplate. That is easily achieved by making one library a dependency of the other. But the user of a XML library should not need to include an HTTP server (nor should an HTTP server require a XML library). The solution is to make use of minimal typeclasses provided by Anticipation to maximally decouple independent libraries.

Small APIs

Every API introduced by a Soundness library should fit on one side of a business card. It should never be difficult to learn, and composition of APIs should be preferred over specialized solutions. Names should be meaningful and appropriately unique: that is to say, sharing a name with an existing concept or entity if they represent that entity, but introducing new nomenclature if they represent something new. Short names are preferred, but arbitrarily-abbreviated names are not. Objects are primarily composed through selection (the . operator) and application, rather than monadic mapping and flat-mapping, since exceptional cases may be handled with checking. The amount of code in each library should also be small.

Other common features

  • extensive use of the immutable IArray[Byte] type for random-access byte-data
  • streaming provided using LazyLists
  • use of the T | Unset union type for optional parameters, without the need to wrap T in Some or use null

Future features

Capture Checking

Soundness projects already use Scala 3's enhanced exception checking, and in the future, streaming APIs built on LazyLists will be enhanced to use the experimental capture-checking functionality that is expected to be introduced in Scala 3 soon to provide better safety.

Soundness Modules

Acyclicity  Adversaria  Ambience  Anticipation  Aviation  Baroque  Caesura  Cardinality  Cataclysm  Cellulose  Charisma  Chiaroscuro  Contextual  Contingency  Cosmopolite  Dendrology  Digression  Dissonance  Diuretic  Escapade  Escritoire  Eucalyptus  Exoskeleton  Fulminate  Galilei  Gastronomy  Gesticulate  Gossamer  Guillotine  Harlequin  Hieroglyph  Honeycomb  Hyperbole  Imperial  Inimitable  Iridescence  Jacinta  Kaleidoscope  Larceny  Mercator  Merino  Mosquito  Nectary  Nettlesome  Octagenarian  Oubliette  Panopticon  Parasite  Polyvinyl  Probably  Profanity  Punctuation  Quantitative  Rudiments  Savagery  Scintillate  Serpentine  Spectacular  Surveillance  Symbolism  Tarantula  Telekinesis  Turbulence  Ulysses  Umbrageous  Villainy  Wisteria  Xylophone Zeppelin

About

A platform of libraries for Scala 3

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages