From 50a0be7f16dfbe60d112bfcef393ee327de019ae Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Oct 2025 17:56:15 +0000 Subject: [PATCH 1/7] Initial plan From 97790f2f8b0d35693cc1b2fd4dc4d870a8907a96 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Oct 2025 18:03:42 +0000 Subject: [PATCH 2/7] Improve README: add introduction, philosophy, examples, and build instructions Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com> --- README.md | 226 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 222 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index da2956e9..ddcb23c0 100644 --- a/README.md +++ b/README.md @@ -8,9 +8,227 @@ codecov

-# Scafi 3 +# ScaFi 3 -**scafi3** is a Scala 3 DSL for _Aggregate Programming_. +**ScaFi 3** (Scala Fields 3) is a modern Scala 3 DSL and toolkit for **Aggregate Programming**, a paradigm for designing resilient and self-organizing distributed systems. -Roots its foundations on the concept of **computational fields**: -a _distributed data structure_ manipulated by _aggregate_ functions implementing the business logic for **large-scale distributed systems**. +## 🌟 What is Aggregate Programming? + +Aggregate Programming enables you to program collective behaviors across networks of devices—from IoT sensors to robot swarms—by thinking in terms of **computational fields**: distributed data structures that span across the entire system. Instead of programming individual devices, you express global behaviors that automatically adapt to the network topology and evolve over time. + +## 🎯 Philosophy and Design + +ScaFi 3 embraces a **functional, composable, and type-safe** approach to distributed programming: + +### Computational Fields First +At its core, ScaFi operates on **fields**: values mapped across space and time in a distributed network. A field might represent temperatures across sensors, distances from a source, or any aggregate value. Fields are first-class citizens that you can manipulate with aggregate operators. + +### Effect System Integration +ScaFi 3 leverages Scala 3's advanced type system and **effect tracking** to provide compile-time safety guarantees: + +- **Safer Exceptions**: Using Scala 3's `throws` clauses, functions explicitly declare what exceptions they can throw, enabling better error handling at compile time +- **Context Functions**: The framework uses `using`/`given` for implicit context passing, making the aggregate computation context available without boilerplate +- **Type-Level Guarantees**: Strong typing ensures that field operations are correctly aligned and serialization is properly configured + +### Programming Style + +ScaFi programs are: +- **Declarative**: Express *what* the system should compute, not *how* each device should behave +- **Composable**: Build complex behaviors from simple, reusable building blocks +- **Resilient**: Automatically handle device failures and network topology changes +- **Pure**: Computation logic is separated from side effects and device-specific concerns + +## 📦 Installation + +### With SBT + +Add ScaFi 3 to your `build.sbt`: + +```scala +libraryDependencies ++= Seq( + "it.unibo.scafi" %%% "scafi3-core" % "1.0.5", + // For distributed systems support + "it.unibo.scafi" %%% "scafi3-distributed" % "1.0.5" +) +``` + +ScaFi 3 supports **JVM**, **JavaScript**, and **Native** platforms through Scala's cross-platform compilation: + +```scala +// For a specific platform, use %% instead of %%% +libraryDependencies += "it.unibo.scafi" %% "scafi3-core" % "1.0.5" +``` + +### With Mill + +Add ScaFi 3 to your `build.sc`: + +```scala +import mill._, scalalib._ + +object myproject extends ScalaModule { + def scalaVersion = "3.7.3" + + def ivyDeps = Agg( + ivy"it.unibo.scafi::scafi3-core:1.0.5", + // For distributed systems support + ivy"it.unibo.scafi::scafi3-distributed:1.0.5" + ) +} +``` + +For cross-platform projects with Mill: + +```scala +import mill._, scalalib._, scalajslib._, scalanativelib._ + +object myproject extends Cross[MyProjectModule](JVMPlatform, JSPlatform, NativePlatform) + +class MyProjectModule(val platform: Platform) extends CrossPlatformScalaModule { + def scalaVersion = "3.7.3" + + def ivyDeps = Agg( + ivy"it.unibo.scafi::scafi3-core::1.0.5", + ) +} +``` + +## 🚀 Quick Start + +### Basic Field Operations + +The foundation of ScaFi is the **field calculus**, which provides three core primitives: + +```scala +import it.unibo.scafi.language.xc.ExchangeLanguage +import it.unibo.scafi.language.xc.calculus.ExchangeCalculus +import it.unibo.scafi.libraries.FieldCalculusLibrary.* +import it.unibo.scafi.libraries.CommonLibrary.localId + +// Define your aggregate program using context functions +def myProgram(using context: ExchangeCalculus & ExchangeLanguage): Int = + // neighborValues: share a value with neighbors and get their values back + val neighborIds = neighborValues(localId) + + // evolve: maintain state across rounds (like a distributed variable) + val roundCount = evolve(0)(count => count + 1) + + // share: compute values while sharing them with neighbors + val consensus = share(0)(neighborValues => + (neighborValues.toIterable.sum + roundCount) / (neighborValues.size + 1) + ) + + consensus +``` + +### Distance Gradient + +A classic aggregate programming example—computing distance from a source: + +```scala +import it.unibo.scafi.libraries.GradientLibrary.* +import it.unibo.scafi.libraries.CommonLibrary.* +import it.unibo.scafi.message.Codables.given + +def gradient(using context: ExchangeCalculus & ExchangeLanguage): Double = + // Compute distance from source using neighbor distance + edge cost + distanceTo[Array[Byte], Double]( + source = localId == 0, // Device 0 is the source + distances = neighborValues(1.0) // Each hop costs 1.0 + ) +``` + +### Domain Splitting with Branching + +Control information flow with domain branching: + +```scala +import it.unibo.scafi.libraries.BranchingLibrary.* + +def conditionalBehavior(using context: ExchangeCalculus & ExchangeLanguage): String = + val distanceFromSource = gradient + + // Split the network into two independent computational domains + branch(distanceFromSource < 5.0)( + "Close to source: " + distanceFromSource + )( + "Far from source: " + distanceFromSource + ) +``` + +### Exchange Calculus: The Foundation + +Under the hood, ScaFi implements the **Exchange Calculus**, a more expressive variant of field calculus: + +```scala +import it.unibo.scafi.libraries.ExchangeCalculusLibrary.* +import it.unibo.scafi.language.xc.syntax.ReturnSending.returning + +def exchangeExample(using context: ExchangeCalculus & ExchangeLanguage): Int = + // exchange: send and receive different values + exchange(0) { receivedValues => + val maxFromNeighbors = receivedValues.withoutSelf.max + val myValue = localId + maxFromNeighbors + + // Return one value but send another to neighbors + returning(myValue) send (myValue + 1) + } +``` + +### Complete Example: Self-Healing Gradient + +Here's a complete example showing ScaFi's resilience: + +```scala +import it.unibo.scafi.language.xc.{ExchangeLanguage, ExchangeCalculus} +import it.unibo.scafi.libraries.GradientLibrary.* +import it.unibo.scafi.libraries.CommonLibrary.* +import it.unibo.scafi.message.Codables.given + +// Define an aggregate program that computes a self-healing gradient +def selfHealingGradient( + isSource: Boolean, + hopDistance: Double = 1.0 +)(using context: ExchangeCalculus & ExchangeLanguage): Double = + + // Automatically computes and maintains shortest distance from source + // Adapts to topology changes and device failures + distanceTo[Array[Byte], Double](isSource, neighborValues(hopDistance)) + +// In practice, this would be executed by the ScaFi engine across devices +// Each device runs the same program but operates on its local context +``` + +## 🏗️ Key Concepts + +### Shared Data Types +`SharedData[T]` represents a field value—a mapping from device IDs to values of type `T`. It includes: +- The local value on the current device +- Values received from aligned neighbors +- Combinators for field manipulation (map, flatMap, etc.) + +### Alignment +ScaFi automatically manages **alignment**: ensuring that values from different parts of a computation are correctly associated across devices. The alignment mechanism uses tokens derived from the program structure. + +### Context Functions +The `using` syntax provides implicit access to the aggregate computation context, which includes: +- Device ID and neighbor information +- Message history for state evolution +- Network communication primitives + +## 🔧 Advanced Features + +- **Multi-platform**: Run on JVM, JavaScript (browser/Node.js), and Native targets +- **Type-safe serialization**: Automatic codecs with compile-time guarantees using the `CodableFromTo` type class +- **Modular libraries**: Compose pre-built libraries for common patterns (gradients, broadcasting, leader election) +- **Integration ready**: Distributed module for real network deployments with socket-based communication + +## 📚 Learn More + +- **Examples**: Check the test suite for comprehensive examples +- **API Documentation**: [ScalaDoc](https://scafi.github.io/scafi3/) +- **Research**: Based on the [Aggregate Computing](https://doi.org/10.1109/MC.2015.261) research + +## 📄 License + +ScaFi 3 is released under the [Apache 2.0 License](./LICENSE). From 093204d1490ba6db79836026a00f776d0bc2a720 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Wed, 15 Oct 2025 18:16:27 +0000 Subject: [PATCH 3/7] Complete README improvements with verified examples and instructions Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com> --- README.md | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/README.md b/README.md index ddcb23c0..9e2b5a20 100644 --- a/README.md +++ b/README.md @@ -102,8 +102,7 @@ The foundation of ScaFi is the **field calculus**, which provides three core pri ```scala import it.unibo.scafi.language.xc.ExchangeLanguage import it.unibo.scafi.language.xc.calculus.ExchangeCalculus -import it.unibo.scafi.libraries.FieldCalculusLibrary.* -import it.unibo.scafi.libraries.CommonLibrary.localId +import it.unibo.scafi.libraries.All.* // Define your aggregate program using context functions def myProgram(using context: ExchangeCalculus & ExchangeLanguage): Int = @@ -126,13 +125,11 @@ def myProgram(using context: ExchangeCalculus & ExchangeLanguage): Int = A classic aggregate programming example—computing distance from a source: ```scala -import it.unibo.scafi.libraries.GradientLibrary.* -import it.unibo.scafi.libraries.CommonLibrary.* -import it.unibo.scafi.message.Codables.given +import it.unibo.scafi.libraries.All.* -def gradient(using context: ExchangeCalculus & ExchangeLanguage): Double = +def gradient(using context: ExchangeCalculus & ExchangeLanguage { type DeviceId = Int }): Double = // Compute distance from source using neighbor distance + edge cost - distanceTo[Array[Byte], Double]( + distanceTo[Double, Double]( source = localId == 0, // Device 0 is the source distances = neighborValues(1.0) // Each hop costs 1.0 ) @@ -143,9 +140,9 @@ def gradient(using context: ExchangeCalculus & ExchangeLanguage): Double = Control information flow with domain branching: ```scala -import it.unibo.scafi.libraries.BranchingLibrary.* +import it.unibo.scafi.libraries.All.* -def conditionalBehavior(using context: ExchangeCalculus & ExchangeLanguage): String = +def conditionalBehavior(using context: ExchangeCalculus & ExchangeLanguage { type DeviceId = Int }): String = val distanceFromSource = gradient // Split the network into two independent computational domains @@ -161,18 +158,17 @@ def conditionalBehavior(using context: ExchangeCalculus & ExchangeLanguage): Str Under the hood, ScaFi implements the **Exchange Calculus**, a more expressive variant of field calculus: ```scala -import it.unibo.scafi.libraries.ExchangeCalculusLibrary.* -import it.unibo.scafi.language.xc.syntax.ReturnSending.returning +import it.unibo.scafi.libraries.All.* def exchangeExample(using context: ExchangeCalculus & ExchangeLanguage): Int = // exchange: send and receive different values exchange(0) { receivedValues => val maxFromNeighbors = receivedValues.withoutSelf.max - val myValue = localId + maxFromNeighbors + val myValue = 1 + maxFromNeighbors // Return one value but send another to neighbors returning(myValue) send (myValue + 1) - } + }(localId) ``` ### Complete Example: Self-Healing Gradient @@ -181,9 +177,7 @@ Here's a complete example showing ScaFi's resilience: ```scala import it.unibo.scafi.language.xc.{ExchangeLanguage, ExchangeCalculus} -import it.unibo.scafi.libraries.GradientLibrary.* -import it.unibo.scafi.libraries.CommonLibrary.* -import it.unibo.scafi.message.Codables.given +import it.unibo.scafi.libraries.All.* // Define an aggregate program that computes a self-healing gradient def selfHealingGradient( @@ -193,7 +187,7 @@ def selfHealingGradient( // Automatically computes and maintains shortest distance from source // Adapts to topology changes and device failures - distanceTo[Array[Byte], Double](isSource, neighborValues(hopDistance)) + distanceTo[Double, Double](isSource, neighborValues(hopDistance)) // In practice, this would be executed by the ScaFi engine across devices // Each device runs the same program but operates on its local context From 4d6c0bcae88cafed23441a8c9c08897d9a0bf1f7 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 09:03:05 +0000 Subject: [PATCH 4/7] Remove emojis, update Mill deps to Maven style, add JSS paper DOI Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com> --- README.md | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/README.md b/README.md index 9e2b5a20..f6142f3c 100644 --- a/README.md +++ b/README.md @@ -12,11 +12,11 @@ **ScaFi 3** (Scala Fields 3) is a modern Scala 3 DSL and toolkit for **Aggregate Programming**, a paradigm for designing resilient and self-organizing distributed systems. -## 🌟 What is Aggregate Programming? +## What is Aggregate Programming? Aggregate Programming enables you to program collective behaviors across networks of devices—from IoT sensors to robot swarms—by thinking in terms of **computational fields**: distributed data structures that span across the entire system. Instead of programming individual devices, you express global behaviors that automatically adapt to the network topology and evolve over time. -## 🎯 Philosophy and Design +## Philosophy and Design ScaFi 3 embraces a **functional, composable, and type-safe** approach to distributed programming: @@ -38,7 +38,7 @@ ScaFi programs are: - **Resilient**: Automatically handle device failures and network topology changes - **Pure**: Computation logic is separated from side effects and device-specific concerns -## 📦 Installation +## Installation ### With SBT @@ -70,9 +70,9 @@ object myproject extends ScalaModule { def scalaVersion = "3.7.3" def ivyDeps = Agg( - ivy"it.unibo.scafi::scafi3-core:1.0.5", + ivy"it.unibo.scafi:scafi3-core_3:1.0.5", // For distributed systems support - ivy"it.unibo.scafi::scafi3-distributed:1.0.5" + ivy"it.unibo.scafi:scafi3-distributed_3:1.0.5" ) } ``` @@ -88,12 +88,12 @@ class MyProjectModule(val platform: Platform) extends CrossPlatformScalaModule { def scalaVersion = "3.7.3" def ivyDeps = Agg( - ivy"it.unibo.scafi::scafi3-core::1.0.5", + ivy"it.unibo.scafi:scafi3-core_3:1.0.5", ) } ``` -## 🚀 Quick Start +## Quick Start ### Basic Field Operations @@ -193,7 +193,7 @@ def selfHealingGradient( // Each device runs the same program but operates on its local context ``` -## 🏗️ Key Concepts +## Key Concepts ### Shared Data Types `SharedData[T]` represents a field value—a mapping from device IDs to values of type `T`. It includes: @@ -210,19 +210,19 @@ The `using` syntax provides implicit access to the aggregate computation context - Message history for state evolution - Network communication primitives -## 🔧 Advanced Features +## Advanced Features - **Multi-platform**: Run on JVM, JavaScript (browser/Node.js), and Native targets - **Type-safe serialization**: Automatic codecs with compile-time guarantees using the `CodableFromTo` type class - **Modular libraries**: Compose pre-built libraries for common patterns (gradients, broadcasting, leader election) - **Integration ready**: Distributed module for real network deployments with socket-based communication -## 📚 Learn More +## Learn More - **Examples**: Check the test suite for comprehensive examples - **API Documentation**: [ScalaDoc](https://scafi.github.io/scafi3/) -- **Research**: Based on the [Aggregate Computing](https://doi.org/10.1109/MC.2015.261) research +- **Research**: Based on [Aggregate Computing](https://doi.org/10.1109/MC.2015.261) and [ScaFi: A Scala DSL and Toolkit for Aggregate Programming](https://doi.org/10.1016/j.jss.2024.111976) -## 📄 License +## License ScaFi 3 is released under the [Apache 2.0 License](./LICENSE). From 38323047daa2a5dd4f01b9908834a27faf239b34 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sat, 18 Oct 2025 09:10:00 +0000 Subject: [PATCH 5/7] Use Mill Maven-style deps (:::) and rename JSS paper to XC calculus Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com> --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index f6142f3c..00ef63e1 100644 --- a/README.md +++ b/README.md @@ -70,9 +70,9 @@ object myproject extends ScalaModule { def scalaVersion = "3.7.3" def ivyDeps = Agg( - ivy"it.unibo.scafi:scafi3-core_3:1.0.5", + ivy"it.unibo.scafi:::scafi3-core:1.0.5", // For distributed systems support - ivy"it.unibo.scafi:scafi3-distributed_3:1.0.5" + ivy"it.unibo.scafi:::scafi3-distributed:1.0.5" ) } ``` @@ -88,7 +88,7 @@ class MyProjectModule(val platform: Platform) extends CrossPlatformScalaModule { def scalaVersion = "3.7.3" def ivyDeps = Agg( - ivy"it.unibo.scafi:scafi3-core_3:1.0.5", + ivy"it.unibo.scafi:::scafi3-core:1.0.5", ) } ``` @@ -221,7 +221,7 @@ The `using` syntax provides implicit access to the aggregate computation context - **Examples**: Check the test suite for comprehensive examples - **API Documentation**: [ScalaDoc](https://scafi.github.io/scafi3/) -- **Research**: Based on [Aggregate Computing](https://doi.org/10.1109/MC.2015.261) and [ScaFi: A Scala DSL and Toolkit for Aggregate Programming](https://doi.org/10.1016/j.jss.2024.111976) +- **Research**: Based on [Aggregate Computing](https://doi.org/10.1109/MC.2015.261) and [XC calculus](https://doi.org/10.1016/j.jss.2024.111976) ## License From 5405471b41ba415b1bef82889ff2f40c66d41d2b Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 19 Oct 2025 08:24:56 +0000 Subject: [PATCH 6/7] Update Mill dependencies to use mvn notation with :: Co-authored-by: nicolasfara <11615611+nicolasfara@users.noreply.github.com> --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 00ef63e1..ccab7031 100644 --- a/README.md +++ b/README.md @@ -70,9 +70,9 @@ object myproject extends ScalaModule { def scalaVersion = "3.7.3" def ivyDeps = Agg( - ivy"it.unibo.scafi:::scafi3-core:1.0.5", + mvn"it.unibo.scafi::scafi3-core:1.0.5", // For distributed systems support - ivy"it.unibo.scafi:::scafi3-distributed:1.0.5" + mvn"it.unibo.scafi::scafi3-distributed:1.0.5" ) } ``` @@ -88,7 +88,7 @@ class MyProjectModule(val platform: Platform) extends CrossPlatformScalaModule { def scalaVersion = "3.7.3" def ivyDeps = Agg( - ivy"it.unibo.scafi:::scafi3-core:1.0.5", + mvn"it.unibo.scafi::scafi3-core:1.0.5", ) } ``` From 1e6f6cd8f9c26360a89ab319106208d5e18f0d32 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Mon, 20 Oct 2025 08:04:53 +0000 Subject: [PATCH 7/7] Fix gradient description and add missing parameter to conditionalBehavior Co-authored-by: cric96 <23448811+cric96@users.noreply.github.com> --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index ccab7031..375f6dbb 100644 --- a/README.md +++ b/README.md @@ -122,7 +122,7 @@ def myProgram(using context: ExchangeCalculus & ExchangeLanguage): Int = ### Distance Gradient -A classic aggregate programming example—computing distance from a source: +A classic aggregate programming example—computing hop count distance from a source: ```scala import it.unibo.scafi.libraries.All.* @@ -142,7 +142,7 @@ Control information flow with domain branching: ```scala import it.unibo.scafi.libraries.All.* -def conditionalBehavior(using context: ExchangeCalculus & ExchangeLanguage { type DeviceId = Int }): String = +def conditionalBehavior(gradient: Double)(using context: ExchangeCalculus & ExchangeLanguage { type DeviceId = Int }): String = val distanceFromSource = gradient // Split the network into two independent computational domains