---
title: "Slice"
description: "A modern IDL and serialization format"
url: https://docs.icerpc.dev/slice
docs_index: https://docs.icerpc.dev/llms.txt
---

> For an index of every page, see [llms.txt](https://docs.icerpc.dev/llms.txt).

# Slice

A modern IDL and serialization format

## IDL for RPCs

Slice is a new [Interface Definition Language](https://en.wikipedia.org/wiki/Interface_description_language) (IDL) that you use to model and describe your network API in a clear and concise manner.

Defining the customary Greeter service interface in Slice is straightforward:

```slice
interface Greeter {
    greet(name: string) -> string
}
```

You don't need to craft special request and reply message types for the `greet` operation: you can specify all your parameters inline.

## Slice and IceRPC

You can use Slice with any RPC framework, or with no RPC framework at all. Slice is a separate framework that does not depend on IceRPC.

That being said, Slice and IceRPC were developed in tandem and together form what you would typically understand as an "RPC framework".

This chapter describes both Slice and the IceRPC + Slice integration provided by IceRPC.

## Streamlined syntax

Slice provides a readable, modern syntax inspired by Rust and Swift. It includes support for [streaming parameters](https://docs.icerpc.dev/slice/language-guide/stream-parameters.md) with the `stream` keyword, allows you to turn any type into an optional type with the `?` suffix, requires minimal punctuation, and more.

The Slice [primitive](https://docs.icerpc.dev/slice/language-guide/primitive-types.md) types have clear names such as `uint8`, `float64`, and `string`. Slice also includes three built-in generic types: [Sequence](https://docs.icerpc.dev/slice/language-guide/sequence-types.md), [Dictionary](https://docs.icerpc.dev/slice/language-guide/dictionary-types.md), and [Result](https://docs.icerpc.dev/slice/language-guide/result-types.md). And Slice lets you define your own types with [custom](https://docs.icerpc.dev/slice/language-guide/custom-types.md), [enum](https://docs.icerpc.dev/slice/language-guide/enum-types.md), and [struct](https://docs.icerpc.dev/slice/language-guide/struct-types.md).

Last but not least, Slice's [tagged](https://docs.icerpc.dev/slice/language-guide/fields.md#tagged-fields) fields and parameters allow you to update your structs and operations over time without breaking on-the-wire compatibility.

#### Example

```slice
// A TourGuide interface with an operation that describes an attraction defined with Slice.
interface TourGuide {
    audioDescription(attraction: string) -> (
        title: string
        duration: WellKnownTypes::Duration
        recording: stream uint8
    )
}
```

## Code generation

Once you've described your RPCs in Slice, you run the Slice compiler on your Slice definitions to generate code in the programming language of your choice. This generated code makes it easy to send requests to a remote service and later receive the corresponding responses. It also helps you implement this remote service by providing a template to fill in.

For example, the C# code generator generates two C# interfaces and a record struct from the interface `Greeter` shown earlier:

```csharp title="C# generated code - client-side"
internal partial interface IGreeter
{
   Task<string> GreetAsync(
      string name,
      IFeatureCollection? features = null,
      CancellationToken cancellationToken = default);
}

internal readonly partial record struct GreeterProxy : IGreeter, IProxy
{
   public Task<string> GreetAsync(
      string name,
      IFeatureCollection? features = null,
      CancellationToken cancellationToken = default)
      {
         // implemented using IceRPC...
      }
}
```

```csharp title="C# generated code - server-side"
internal partial interface IGreeterService
{
   ValueTask<string> GreetAsync(
      string name,
      IFeatureCollection features,
      CancellationToken cancellationToken);
}
```

> **Note**
>
> The C# code shown above is generated by the IceRPC-specific code generator for C#. In particular, [IFeatureCollection](https://code.icerpc.dev/csharp/0.6.x/api/reference/IceRpc.Features.IFeatureCollection.html) is an IceRPC type.

## Flexible and extensible

You can fine-tune the API generated by the Slice code generators with Slice [attributes](https://docs.icerpc.dev/slice/language-guide/attributes.md). For example, in C#, you can map a sequence to an array (the default), or to a list, or even to a hash set:

```slice
interface Translator {
    getLanguages() -> [cs::type("HashSet<string>")] Sequence<string>
}
```

The `cs::type` attribute changes the mapping for values decoded by the generated code and returned to you. For values you give to the generated code, the mapping for a `Sequence<string>` parameter is always `IEnumerable<string>`.

Slice's custom types allow you to send any type you wish through Slice. You just need to provide methods to encode and decode instances of your custom type.

## Next steps

- [Slice components](https://docs.icerpc.dev/slice/basics/slice-components.md): An overview of each Slice component.
- [Contract-first model](https://docs.icerpc.dev/slice/basics/contract-first.md): Learn how to create an application using IceRPC and Slice.
- [Interface](https://docs.icerpc.dev/slice/language-guide/interface.md): Learn how to define interfaces in Slice.
- [Struct](https://docs.icerpc.dev/slice/language-guide/struct-types.md): Learn how to define and use structs in Slice.
- [Slice encoding](https://docs.icerpc.dev/slice/encoding/overview.md): Learn how Slice encodes types into byte streams.
- [Examples](https://docs.icerpc.dev/slice/basics/examples.md): Discover the Slice syntax through a few examples.
