jlrs icon indicating copy to clipboard operation
jlrs copied to clipboard

Create a website with a tutorial

Open Taaitaaiger opened this issue 1 year ago • 1 comments

The only information that's currently available is contained within the docs. It's hard to provide a step-by-step tutorial that progressively explains how to use jlrs that way, a website and a tutorial is needed.

Summary of plans:

Introduction

The first few tutorials should focus on introducing important concepts in jlrs. I think it's best to start with embedding Rust using the sync runtime because that involves the least amount of prerequisites, and using the same structure as the Embedding Julia doc does.

Sync runtime

  • Create a new binary crate, add jlrs to deps, introduce version features and sync-rt feature
  • Init sync runtime, explain that StackFrame is necessary to make Julia aware of data that is in use from Rust
  • Explain that Julia can't be used arbitrarily, but that all interactions with Julia must happen in a scope
  • Create a scope, call Value::eval("println(sqrt(2)")

Primitive data

  • Introduce Value
  • Show that primitive types like u8 and f64 can be converted to Julia with Value::new, and that they can be unboxed with Value::unbox to convert them to Rust
  • Explain that primitive types are immutable

Modules

  • Show how Julia's module system can be accessed from Rust
  • Show how to load and access installed packages
  • Show how to create constants, and that some methods have two variants: one that catches exceptions, and one that doesn't

Functions

  • Introduce Call trait
  • Access the + function and call it
  • Show that exceptions are caught and returned by calling + with incompatible arguments
  • Introduce named_tuple and WithKeywords
  • Call a function with keyword arguments

Memory management

  • Explain that the frame provided to a scope is used to make the GC aware of Julia data used in that scope
  • In particular, explain the concept of rooting
  • Explain that a Value has a scope lifetime that ensures it can't be returned from the scope that roots it
  • Introduce targets, nested scopes, and ExtendedTarget
  • Explain there are rooting and non-rooting targets, and when it's okay to use a non-rooting target
  • Show how to write functions that take a target generically, either directly or through an ExtendedTarget

Arrays I

  • Introduce Array, explain that it doesn't express the element type or rank at a type level
  • Show that an Array can be created from a Vec as long as the element type of the Vec implements IntoJulia
  • Show that an Array can be created from a slice as long as the element type of the slice implements IntoJulia, introduce the 'data lifetime
  • Explain that the content of an array can be accessed from Rust, but how this must be done depends on the element type
  • Introduce the inline and value layouts of arrays, ignore the details of the bits-union layout optimization but acknowledge its existence
  • Introduce tracking and its limitations

Async runtime

After the introductory material, I think it's best to introduce async runtime before diving into more complex topics.

  • Explain what features are supported by the async runtime
  • Show how to initialize the async runtime
  • Introduce CallAsync
  • Provide examples of blocking, async and persistent tasks

Data

These tutorials dive deeper into topics like Julia types and the layouts of their instances. This information is useful if you want to access or mutate the content of Julia data directly from Rust.

Types and layouts

  • Introduce DataType, UnionAll, Union, TypeName, and TypeVar.
  • Provide some information about the layout of a type.
  • Introduce type constructors
  • Introduce DataType::instantiate

Values

  • Provide information about the functionality provided by Value.
  • Mutate a Value, introduce write barrier
  • Introduce casting and explain how it differs from unboxing
  • Introduce FieldAccessor

Arrays II

  • Introduce TypedArray
  • Introduce bits-union layout optimization
  • Introduce jlrs-ndarray feature

Other types

  • Introduce JuliaString and Symbol
  • Explain that there are more types, most of them only available when the internal-types feature is enabled

Jlrs.Reflect

  • Introduce the functionality of JlrsReflect
  • Provide information about the derived traits, but don't go in-depth about CCallArg and CCallReturn
  • Introduce compatible types

CCall

The final set of tutorials are about calling Rust from Julia, they should focus on the julia_module macro and the functionality that can be exposed to Julia with it.

CCall

  • Introduce Julia's ccall interface
  • Explain that this interface can call extern "C" functions defined in Rust
  • Explain that the crate type must be cdylib to create a library that can be loaded by Julia
  • Introduce the CCall type, explain that it's essentially a sync runtime
  • Introduce leaking

julia_module

  • Introduce julia_module macro and explain what can be exported with it
  • Explain that the CCallArg and CCallReturn traits are used to generate the function and ccall argument and return types
  • Introduce the RustResult type, explain why functions called through ccall should never throw an uncaught exception

Constants and globals

  • Show that static and const global data that implements IntoJulia can be exported as either a module constant or global

Freestanding functions, opaque types, and their methods

  • Show that unsafe extern "C" functions can be exported
  • Introduce TypedValue
  • Show how to return a RustResult from an exported function
  • Introduce OpaqueType trait, explain that it can be used to expose Rust data to Julia
  • Show that methods of opaque types can be exported similarly to unsafe extern "C" functions
  • Explain and show that methods of opaque types can take &self or &mut self

Foreign types and their methods

  • Introduce the ForeignType trait, explain its similarities to and differences from OpaqueType
  • Show how to correctly mark and mutate Julia data referenced by foreign types

Async function calls

  • Explain that long-running ccall'ed functions that don't allocate Julia data can prevent the GC from running
  • Introduce the AsyncCCall trait

JLL packages

  • Provide an example recipe for Yggdrassil

Taaitaaiger avatar Apr 26 '23 18:04 Taaitaaiger