---
# System prepended metadata

title: cadCAD Spaces Community Call

---

# cadCAD Spaces Community Call

## Objectives
The October cadCAD community call we'll be demonstrating comparisons between the (prospective) implementation of spaces in Reference, cadCAD.jl, and cadCAD.rs as they relate to the GDS paper and each other. This will be a major milestone and of deep interest for the technical side of the community. Socializing fundamental constructs across implementations of cadCAD as they relate to GDS helps kick off the heavy lifting of closing the existing education and communication gaps and enables onboarding of technical community members for contribution and early feedback. Finally, it gives a chance for the broader community to put faces to each of the efforts.

We also need to organize the teams and various efforts.This doc represents a kick-off to the conversations on (1) "how do we work want to work together"; (2) "who's been doing what"; (3) "are we on the same page about what cadCAD and GDS is"; and (4) what do we want to say during the community call.

## Community Call
## Teams
(still need to fill in context data. Please add whatever you see is helpful)

### GDS / Math Spec
@mzargham 
Jamsheed Shorish
https://research.wu.ac.at/en/publications/generalized-dynamical-systems-part-i-foundations

https://medium.com/block-science/generalized-dynamical-systems-part-i-foundations-74505bbdf0e

https://hackmd.io/bdtW0ngxReqALhc1NkOf8g

### Reference
Status:
- End to end simulation under testing
- Unit testing
- function-level documentation

Next: Domain specific langauge for pipelining blocks

@emanuellima 
@mzargham 
https://github.com/mzargham/fantasy-cadcad
https://github.com/cadCAD-org/cadCAD-ri

willwolf testing support

### Julia
Julia community is as valuable as the performance of the language.

Domain scientists who often spend years on their respective field use it and maintain high quality scientific computing packages.

Prominent research organizations also use Julia, and one such example is the Scalable Integrated Infrastructure Planning framework by NREL, another - Catlab.jl.

Status:
- `Plurigrid.jl` is the package that needs to integrate `cadCAD.jl`, `Catlab.jl`, and `NREL SIIP`
- spaces in progress (to review)

Next:
- set (bi) weekly sprints for feedback and alignment on design


@barton 
@mathfax 

https://github.com/cadCAD-org/cadCAD.jl

https://github.com/Plurigrid/cadCAD.jl
(need to pull back in as 'dev' branch to cadCAD repo)

### Rust
Status: Spaces ready to test
next: implement blocks

willwolf
@Brock 
@Ben10 | CADLabs 

https://github.com/cadCAD-org/cadCAD-rust

### cadCAD org
status: 
- dev docs led by brock

## Spaces
*(let's start defining what spaces are and how they work in each context)*

- Spaces have to be a collection of dimensions
- A dimension is a pair name that is a string and either regular type or another space
    - nested spaces
- Spaces have to be able to:
    - "+"
    - "*"
    - "**" power
    - ".name"
    - .dimensions
    - rename dimensions
    - is empty
    - unroll schema
    - is equivalent
   


### GDS

Space: (Primitive Structure)
A Space is a pointer to a collection of dimensions.

> h x ∈ XC , there exists
    > at least one initial condition x0 ∈ X and a sequence of some length n such that x ∈ R(xn−1), where R(xn−1) is
    > generated from some Rn(x0).

### Reference



### Julia



### Rust




https://github.com/cadCAD-org/cadcad-rust/tree/ww/define-space-and-dimension

## Questions
1) In the GDS paper, there is a distinction made between a State space and a Configuration Space.

    > h x ∈ XC , there exists
    > at least one initial condition x0 ∈ X and a sequence of some length n such that x ∈ R(xn−1), where R(xn−1) is
    > generated from some Rn(x0).


    When referring to a Space as implemented in code, which "Space" is being refered to (State or Configuration)? And per the conversation included below, how is it that a point becomes the executing instance of the code? It seems ontologically more difficult to discuss a Spaces implementation if it must be done in terms of a point at runtime and not tangentially (interface, inheritance, etc.)
    
    **Answer:**

2) A Space is a general concept (it can be understood as an Abstract Class that other spaces adhere to).
    - all statespaces are spaces
    - not all spaces are statespaces
    - a specific system (model) will have its own statespace
    - a specific system model may be said to have a configuration space, which is the subspace of the statespace that is actually reachable given the specific system (model) 

---
# Conversations, Notes

This is a tool for representing things, AND then having those representations become executable. The modeler constructing an ontology — at any snapshot of the ontology you have a strongly typed system, but when your doing design work your fiddling with that very thing


  7:24 AM
- Space
    - Abstract Base Class
- MySpace
    - Abstract Class
- PointOfMySpace
    - Class
- pointOfMySpace
    - instance
By constructing this hierarchy we can think of *Space as “Protocol for abstract classes called spaces”*. basically any abstract class satisfying the rules of space-- from the sounds of it, in Rust, Space is just the generic Struct, and that MySpace is just the type assignment for that struct. If thats the case then MySpace (abstract class) and PointOfMySpace (class) are not differentiated. I think this is okay — this would imply that the 4 deep hierarchy is actually part of the python black magic and that the “true” ontology is:
- Space
    - Abstract Base Class
- PointInMySpace
    - Class
- pointInMySpace
    - Instance

To me this still feels compressed because in “modeler time” i am not thinking about points i am thinking about the shape of the Space those points belong to (essentially a schema). For me thats “MySpace” rather than “PointInMySpace” but i can see how strongly typed structures make those essentially the same.

What’s interesting is that the first (4 deep) hierarchy feels more natural mathematically but the second (3 deep) feels more natural from a programming perspective. Python (due its lack of strong typing, forced us into the first one anyway). It seems like a good time to ask WWJD (what would Julia do?)


There has been importance placed on separating structure (Spaces) from function (Blocks). So, in a sense, Points inherit their lack of functionality from Spaces. To me, a Space maps to a schema, and a Point in a Space maps to a tuple that conforms to the Space's schema.
15 replies


  1 day ago
To me, a Space maps to a schema, and a Point in a Space maps to a tuple that conforms to the Space's schema.
this sounds exactly like (in python) a class, and an instance of that class, respectively.
in the most pure/simple/vanilla sense. (edited) 


  1 day ago
Yes, it does, and we had much discussion about this, but we wanted to put them on different classes to keep spaces as pure types, that when operated on produce other types, not instances. If a point were a simple instantiation of a space, when summing two spaces we would sum the data of the point or the schema? We chose to sum the schema, so a point cannot be an instance


  1 day ago
In Rust, this will be different, no doubt


  1 day ago
If a point were a simple instantiation of a space, when summing two spaces we would sum the data of the point or the schema?
yes, it would sum the data (where the ability to actually “sum” the points would be prescribed by the modeler, then enforced by the compiler, explicitly, at least in a typed language; said differently, it implicitly sums first, the schema, i.e. type compatibility is enforced; then second, the data), not (just) the schema.
this said, why is summing the schema important? what benefit does it bring, to who? (edited) 



  24 hours ago
It is the mechanism by which Spaces (call them element Spaces) can be used to compose a new Space such that the element Spaces are all subspaces within the new Space.


  24 hours ago
Space algebra?


  24 hours ago
where the ability to actually “sum” the points would be prescribed by the modeler
We don't want that. We want the lib to provide all basic actions on a standard way.
why is summing the schema important? what benefit does it bring, to who?
It is one of the most important requirements of the lib. It gives the modeler the ability to create new spaces through an algebra during prototyping time.


  22 hours ago
ok. this makes sense :point_up_2:
this said, can you share a motivating example / pseudocode?


  21 hours ago
My examples are usually contrived because I am much more of a software engineer than a modeler, but it would go like this:

```
@space
class Savanah
    zebra_pop: int
    lion_pop: int

 
... do my stuff ...

# but now I want to see how things behave with a different actors under different rules

@space
class AnotherSavanah
    gazelle_pop: int
    cheetah_pop: int

# ... do my stuff ...

# and now I want to complicate things and put it all together under more complex rules of interaction
# so instead of redeclaring a space from scratch, I want to be able to reuse spaces:

NewSavanah = Savanah + AnotherSavanah

# ... do my stuff ...
```

  20 hours ago
i’d love to see an example model with, and without, the syntactic sugar.
(on a similar note, what is different about Savanah and AnotherSavanah besides, simply, names—of classes and variables?) (edited) 


  20 hours ago
Again, the problem is the contrived examples. Imagine Savanah and AnotherSavanah have 10 dimensions each with completely different types.


  20 hours ago
(right, so my reaction is, ok, define a different struct/class for each.)
even with space algebra, you still have to write all the code to process the new space, no?
since NewSavanah now has 20 dimensions (each with names), whereas Savanah had 10?


  20 hours ago
you mean blocks?
then yes, probably a block logic that deals with Savanah is going to be different to the one that deals with NewSavanah

re the “space” and “point in that space” intimated on the attached slides…
and aside from mutability of the name of each object member; (let’s address that in isolation);
where do the following implementations fall short?

```
# rust

struct IntegerCartesianPoint {
    x: i64,
    y: i64
}

struct FloatPolarPoint {
    r: f64,
    theta: f64
}

let xy_in = IntegerCartesianPoint { x: 30, y: -30 };

let xy_fl = FloatPolarPoint { x: 90, y: 60 };
```
```
# python

@dataclass
class IntegerCartesianPoint:
    x: int
    y: int

@dataclass
class FloatPolarPoint:
    r: float
    theta: float

xy_in = IntegerCartesianPoint(x=30, y=-30)

xy_fl = FloatPolarPoint(x=90, y=60)
```

When, in (typed) pseudo code, the user would define a block as:
```
def my_block(domain: IntegerCartesianPoint) -> FloatPolarPoint
```

  24 hours ago
It falls short here, in Python:
```
NewSpace = IntegerCartesianPoint + FloatPolarPoint 
```
 ^This fails

So the spaces cannot be dataclasses or simple classes because we need extra actions. So we have Space as a kind of class factory that produces MySpaces. We chose MySpaces to not be instantiable to disambiguate between action on the type and action on the point (or instance). So the overloads of MySpace, such as __add__ sum the space itself, not it's instances.
So it falls short again when doing:
xy_in + xy_fl
In rust it may or may not fall short, I haven't thought much about Rust yet.
:+1:

  22 hours ago
ok. this, as a hard requirement, now makes sense.
however, my next line of questioning is why it is a hard requirement, since it makes things more complicated.
(i’m very pragmatic, pardon :slightly_smiling_face:)

  21 hours ago
Because the user must be able to create new spaces programatically, in addition to explicitly.

  21 hours ago
i’m asking why the user must be able to do this :slightly_smiling_face:
since, this capability, create new spaces programatically, comes at a high implementation cost, imo.

  21 hours ago
Because it's a very common pattern and a very desirable functionality. A lot of cadCAD features come with a high implementation cost, but that's just unavoidable.
:+1:
1

  21 hours ago
how common? have many people asked for this?
(i’ve never wanted to, nor even considered, doing this myself, for reference.)
(for whatever it’s worth, i’ve been using legacy cadcad heavily for about 6 months.)

  20 hours ago
in my experience, most people simply want to use tools that they know, e.g. the raw language constructs, and only use other people’s tools if they are 1) black box magic 2) make their lives significantly easier, i.e. serve as a very useful point of automatic/abstraction 3) Just Work, and don’t incur undue “go debug this really weird thing you know nothing about.”
in this vein, if people truly want this syntax, we should give it to them. however, if they don’t, i remain skeptical.
(but hey, skepticism is my job! the continued examples/info are helpful.)

  20 hours ago
I think people want this syntax, yes, because we brainstormed it with modelers from inside BSci, like Z and Danilo. Of course, by receiving further feedback from other modelers, we can change the UX/UI, but just because you have never found a use for a portion of Numpy's API, that doesn't mean Numpy shouldn't have it. cadCAD should give options and flexibility to very different use cases.


  20 hours ago
just because you have never found a use for a portion of Numpy's API, that doesn't mean Numpy shouldn't have it.
well, numpy has it if other people want it, presumably. (edited) 

  20 hours ago
exactly

