[Edu-sig] Quadrays again... cross-training in two langauges

kirby urner kirby.urner at gmail.com
Sun Aug 9 17:45:26 CEST 2015

On Thu, Aug 6, 2015 at 10:35 AM, Kirby Urner <kurner at oreillyschool.com>

> I've posted about Quadrays on edu-sig before.... going back and forth
> between two languages may be a good way to learn both, or to learn one
> using one's knowledge of the other.  In this case, I'm developing the same
> Quadray class in Python and Clojure.
> I'll followup with a link to the Clojure version.

This will do for now:


In a Python -> Java -> Clojure spiral we do a lot of the same conceptual
stuff at each level.

Vector stuff is "ground floor" and graphical, moving up to Website on a
server, maybe with Clojurescript for a browser.  We start with geometric
primitives such as polyhedrons, to go along with our introduction to
"objects" in the OO sense.

The audience for Websites does not have to be "the public" i.e. a tool used
inhouse to do an existing job is more our focus.  My background is in
medical research, heart stuff in particular.  Why not start with the heart
as a STEM topic?

I want to get away from always doing something eCommerce when teaching
website design.  Let others stick to that example.

Clojure has a lot of embedded Java thinking.  Yes, I included Supermarket
Math in my Digital Math curriculum, but that doesn't force our hand when it
comes to web frameworks.

The idea of an interface has migrated to that of a "protocol" which
provides a ready namespace for a "record".

An interface is like a contract with an empty API:  the control panel is
specified but no how it's wired, because the same control panel may be used
to fly very different types of airplane.  Here's what it looks like to
specify a Java-style interface an Clojure, which I think use as the same
API for two types of vector:

(defprotocol VectorOps
  (add [this other])
  (sub [this other])
  (len [this])
  (neg [this])
  (norm [this]))

i.e. vectors are things you want to add (A + B), subtract (A - B) get the
length of, negate, normalize (put in some canonical form).

Both types of vector stick to the abstract algebra notion that A - B is
syntactic sugar for A + (-B) i.e. if you have the notion of negation, then
you get subtraction for free as to subtract X is simply to add the negative
of X.

Both types of vector embody that idea, in both languages:


    def __sub__(self, other):
        return self + (-other)


    (sub [this other] (add this (neg other))))

As I mention on the Clojure list, when coding in an OO language, one has a
choice to make ones types more or less immutable.

My vectors are "hardened" with immutability in the sense that -A does not
"negate A in place" i.e. we do not keep the name A while making the vector
point 180 opposite where it pointed before.

FP is the enemy of such mutability, but is a way of thinking not just a
particular language.

In both my vector types, Quadray and XYZ, -A returns a new vector, as do
all the vector ops, except len(), which returns a float, the length of said

Where I would typically go from here is into "string substitution
territory" i.e. interpreting vectors visually, as points and/or edges,
inside a 2D or 3D environment.  We'd interpolate into POV-Ray and or
VRML-like scaffolding, with lots of settings pre-set.  This was the object
of my stickworks.py. [1]

As I joked on the Clojure list, 2D vs. 3D does not necessarily mean flat
vs. spatial as both POV-Ray stills VPython's moving displays implement
perspective.  The screen is 2D in both cases.  So forget about the Z axis
(so subtract that dimension) i.e. we're not really using it.  3D = 2D
(still) + Time, i.e. animation.

2D is manga, 3D is anime.  3D vs 4D is when you bring the Z axis back.

That's a curious namespace and probably only used to tickle their brains
with this slippery word "dimension" of so many meanings (uses).  [2]

Back to OOP vis-a-vis FP, we should think about whether we want the same
"hardening against mutable state" in our Polyhedron objects, or do we want
to allow them to rotate and preserve identity at the same time?

Clojure has constructs for that (e.g. atoms), if we decide we really need

I think we should explore staying rather strictly immutable and consider
each frame of film its own polyhedron e.g.   icosa = icosa.rotate(A, 60)
would output a new polyhedron, to which the same name is rebound (or not,
as the case may be).

The other option would be icosa.rotate(A, 60) where it rotates "in place"
and returns None.

Maybe in Python we could to with rotated(P, axis, degrees) and
P.rotate(axis, degrees) as the two alternatives, mirroring sorted/sort and


[1]  http://showmedo.com/videotutorials/video?name=1010040&fromSeriesID=101

[2]  In other contexts I use 4D for pure spatial (sans time) because the
tetrahedron encapsulates the whole idea of volume and Quadrays use four
basis rays, not six, not three.  The "threeness" of "three dimensional"
relates to either of two zig-zags i.e. 3D + 3D = 6D Tetra -- where D means
"diameter of unit sphere" in closest packing.  Both Zs hafta be there as 6
is the minimum "cage".  But then that's D for diameter.

When it comes to Dimension, spatially that's a four, but time/size is
always present in addition, so that makes five (and the possibility of
special case events i.e. realized 4D shapes).

Geometers and "schooled" people speak of length, breadth, and height as
constituting a hierarchy of three independent dimensional
"two-dimensional," and "three-dimensional"__which can be conjoined like
building blocks. But length, breadth, and height simply do not exist
independently of one another... [ S. 527.702 ]

But that's even more remote than before!  Praise Allah for namespaces!

I'm influenced by Karl Menger and his "geometry of lumps" ideas.

"There is no dimension without time." (S. 527.01)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/edu-sig/attachments/20150809/d2daa58d/attachment.html>

More information about the Edu-sig mailing list