RhinoCommon data types mutable?

I’m accessing rhinocommon mostly through ironpython
Can someone tell me what data types are mutable and what not?
I’m guessing Point3d is immutable like an integer. A brep is probably mutable like a python dictionary. Is that right? what about curves, planes, lines, box, etc…?

HI @Will_Wang,

Why is this information important to you? What problem would this help you solve?

– Dale

I’m asking this because of a few instances where I unexpectedly modified mutable objects. It never stopped me from writing a functional script (I probably started making copies of suspected mutable objects). But I wanted to be more aware and maybe write scripts that don’t create in-memory copies too often
I understand if this may expose algorithms/computational thinking by the software creators and you’d rather keep it private. Thought I’d just toss the question on here.

Hello, although you can access rc by ironpython this always ends up in a lot of questions if you don‘t understand C#. Therefore I strongly advice to dive into C#. In C# there is a difference between a struct and a class (which is not equal to C++).
Structs in C# are passing data per value (like any simple value data type, such as integers).

So lets take a point of type Point3d (struct) -> whenever you say pt1 = pt2, you copy data because it copies its values. However „pt1“ stays a different instance.
If Point3d would be a class instead, basically the same expression would say instance „pt1“ is now instance „pt2“. You are passing data per reference , meaning the memory address of instance 1 becomes the memory address of instance 2, which makes them virtually the same object.
However this does not mean that a struct like Point3d is immutable. You can always modify them or passing them as reference as well („ref“ keyword(C#)).
To answer your question, in rc all objects being structs are what you consider as being „immutable objects“

I definitely agree. However, ‘rhinoscriptsyntax’ doesn’t have the full range of straightforward methods and properties I can call with rc.

I think this will help for sure. Thanks!

Hi Tom

This is true in C#, but in IronPython C# structs seem to have been turned into classes
( Python has no structs )

import Rhino

pa = Rhino.Geometry.Point3d( 11, 22, 33 )
pb = pa
pb.X = 88
print pa

Or did I misunderstand your words ? :slight_smile:


Point3d is mutable. Most RhinoCommon types are mutable (all the ones you mention are mutable). This adds a layer of complexity but allows to also change values while doing operations, making some small inner modifications slightly more efficient (imagine changing the X coordinate of the first point of an immutable Line, with 2 immutable Point3ds: if it were immutable, a lot of values would need to be copied to just change one).

You can use most simple types as immutable. Especially Point3d can be thought as immutable if you use only operators, like +, + etc, among Point3ds.

Everything is an “object” in Python (it is always passed as a reference).

Does it help?



Giulio Piacentino
for Robert McNeel & Associates

actually I‘m not quite sure. Haven‘t done much coding in IronPython recently. I was expecting this behaviour for IronPython as well, since the thread owner was describing this and Point3d is part of a C# library and this object is created by an C# Constructor. Unfortunate I cannot test it right now, so I guess „pa.X“ returns 88? Then it’s definitely passed by reference.
I think it does not have to be a class to get passed by ref, this is up the programmer. It just says you always pass the address, no matter how small that chunk of memory is. I know that everything is allocated on the heap in CPython, but I remember this is not necessarily true for other implementations. So if you consider an object as something allocated on the heap, the statement: „Everything is an object“ is not fully true for every Python implementation.I‘m not even sure if a class in Python is technically the same as a C# class, although IronPython was written in C#.
I seriously don‘t know…

However I did say that Point3d is mutable, also in C#. I was thinking the Immutability here was meant as eqvivalent to passing-by-value.

IronPython is really hard to understand😵

1 Like

Yes, exactly. :slight_smile:

Yes, I was not clear.
What I was trying to say is that Point3d and, say Point, which is definitely a class, behave in the same way in Python.

Hehe … this is something I remember well.
In C#, structs don’t need duplication methods, since an assignment is enough, but in Python, when trying to duplicate what in C# is a struct, you may find yourself looking around for some way to duplicate the stupid thing . :smile:

Yes, I think that is what Will was talking about too.
( You are not allowed to modify immutable objects anyway in Python, as far as I understand … )

(Any) Python is difficult to understand for me … but I like writing script with it :slight_smile:

Thank you for your clear explanation !


Although immutability can be achieved in most languages, it makes sense to pick one that has it built in as integral part of the language. F# anyone?

This thread underlines that clearly (:

Does Rhino support F# scripting ?

@Goswin has created an F# scripting plug-in. I don’t know if or when he plans to release it and how. But it works pretty neatly.


My F# editor allows you to do F# scripting in Rhino. But this will not help much with the fact that almost everything is of mutable nature of RhinoCommon.
I mainly use F# because I prefer its syntax over C# and even Python.
@DavidRutten also made a nice post about the benefits of immutability.
My F# editor is still experimental, Let me know if you still want to test it.

Actually I’m just curious about F#.

I still have to learn it, I hope to start learning something in my (too short :wink: ) summer holidays.
Anyway, I think that having a tool to experiment with F# and Rhino would be cool … :slight_smile:

say I have a curve and I have a series of PlaneToPlane xform
I tried using Curve.Transform() but it doesn’t create copies of the curve. What do I have to do to make copies for each xform?
essentially the orient component in grasshopper

var curve_copy = curve.DuplicateCurve();
1 Like