Posts

Showing posts from 2021

Lowering your continuations while lifting your functions (in Python)

 A  Previous post  describes Python code that does functional composition on reversible code. A question that one asks when starting to write compositional code is: how does one compose functions 'at different levels'? And I purposely express this a bit ambiguously as 'different levels' can mean different things. Today we will care about levels within a hierarchy of data containers and simple objects, and note a thing or two on the way. The map function is Python's builtin tool to apply a function over each data of a container. Combined with a lambda or a function definition we can convert fonctions on container elements to functions on containers. Jargon for this type of code is that we are lifting a function to the container. The idea being that a function on a container is higher than function on container elements. An important detail to note, is that while the mapped function is being lifted, the continuation context needs to be 'lowered'. This is beca...

Data composition from functional composition in Python

Previous post describes code that does functional composition. Let's now add operators that convert this functional composition to become data composition, and allow what is produced to be 'executed later'. Github drop for these code snippet here . Key insights in writing code this way are: Data objects are derived from the functions which define their semantics. This is meta-programming 'done backwards'. Like with meta-programming we capture 'what could be interpreted', but we do so through the execution semantics, not by adding an additional meta-language. Data objects execution semantics can be ambiguous until ambiguities are removed. Not far from a "quantum-like" execution model! There are strong ties here to laziness and trampolining . Blockchains are as much about composition of data, as about composition of functions. These example code snippets  are very short (<100 active lines). Two design choices make this possible:  Focus on argument...

Point-free reversible Python

Have you ever wanted to to write 'formal style' in Python? If so, these snippets of code which I shared on gitbub might please you. What is a formal style of programming Formal "code", like formalism in mathematics, is to solidly tie what you write to what you mathematically mean. And that connection goes both ways: from math to expression, from expression to math.  The traditional way to write formal code is to prove as much as you can 'along the way' of writing code. The difficulty of this approach is that proofs are hard, which either limits the complexity of your code, or limits your ability to be productive. Another way to write code with mathematical properties is to assemble pieces of code that already have mathematical properties. When this assembly preserves these mathematical properties, and even better when it scales them, the resulting code has mathematical properties.  A key concept here is that these "pieces of code with mathematical proper...

Retrospective on "my bookshelf picture"

 My previously shared bookshelf picture got a hit peak and this got me thinking:  Most of my books are more than 20 year old. Some are from my dad and his older brothers. That means they are sixty+ years old! (FYI my dad, Socrates Litsios , recently passed away, had a PhD from MIT (operational research in EE department)). I have never been a linear student (except with audio books). I tend not to read books but to read publications. And even then, I skim the publications, I do not read them. However, I do a lot: I program prototype on prototype during my spare time. I implement software for real professionally, mostly in rocket science areas that rely on math. Therefore most of these books still resonate with me, having used much what is in them. That is why I keep them. Once a year I throw out the books that no longer resonate. A month ago I put 30 of these books on a chair on the sidewalk, including my Collected Algorithms from ACM books (mostly Fortran in print). At th...

Stream oriented processing

Here is a presentation on designing stream processing systems which I uploaded to YouTube today . Recorded in ~2014, and given in one form or another a few times since about 2005, it is how I "model with streams", something I learned designing market making and algo systems. What I like most about this old deck is how it stays aligned with modern abstraction expressed in higher-order FP semantics. I wrote a bit on stream processing here in 2011 .  I see also that I have a draft for publishing this presentation in 2013. Yet I had wanted to add Scala or Haskell code that captured the "nice figures" of this presentation, and that is why I held back from sharing it earlier.  All original content copyright James Litsios, 2021.

Single class refactoring exercise (in Python)

This week I needed to extract a little piece of computational geometry, imbedded in a single Python class of application specific logic. Therefore I proceeded to create a second class and migrate the computation geometry code over to it. On of the pleasures of Python is the ability to do this type of refactoring at low cost, and pretty much follow a recipe. Which I include here:  Start with class A Create new class B, derive A from B Move part of A.__init__ to B.__init__ Move initial subset of member functions A to B, implicitly creating a first API between A and B (API A-B) Iterate and apply one or more of: Split / merge methods within API A-B For A still accessed directly (through  self ) by B,  extend API A-B to provide additional A content. Find flow/bundle/fiber/ data of A and B, refactor these to be within new classes C0, C1, .... Alternatively refactor them to be within additional Numpy axes (e.g. for ML applications). Move selected Cs to from A to B or B to A. If ...

Market participants, structural dysfunctions and the GameStop event

At least eight dimensions can be used qualify the way financial participants trade: Transaction speed from slow to quasi-instantaneous. Transaction rate from rare/infrequent to quasi-continuous. Selection of transactions from disorganized to very organized (e.g. backed by mathematics and research). Transaction's future obligations from no future obligations to with future obligations (e.g. backed by personal wealth). Time scope of transaction's obligation from immediate (e.g. transfer cash) to long term (e.g. payout bond coupon after 30y). Number of participants on "same side of transaction" from small to large Size of single transaction from small to large. Influence of fundamental/"real world" properties of traded contract from none to very important. In the context of the GameStop event we note the following:  Traditionally,  retail investors execute transactions: Slowly Infrequently In a disorganized way With no future obligation With only immediate obli...

From sparse tensor parameter space to orchestrated stream of distributed processes

In 1996, my team adopted a tensor view of its application parameter space. Credit must be given to one of my partners at QT Optec/Actant, who presented the following view of the world: each client could "tie" each parameter to any point/slice in "high-dimensional" cartesian space of primary and secondary keys. It was an advanced concept which took me many years to fully master. The simple statement is: "it ain't easy"! Higher dimensional data views are "all the rage" now, but not in 1996. I'll try to illustrate the concept as follows: Imagine we have a parameter P1 used in formula F that goes from X to Y. Imagine that X can be queried with keys kx0 and kx1 (it is two dimensional) and Y is three dimensional with "axis" ky0, ky1, and ky2. P1 is a parameter, which means that it is a "given value". The question is then: is P1 just one value? Should we use a different P1 for the different values of X tied to its 2d mapping ...

What works in higher order Python (Functional Programming, early 2021)

 Here is what works for me to write higher order typed Python: Use class with __call__ instead of lambdas or functions (aka explicitly specify each closure). Favor constraining types with Callable , ParamSpec and Concatenate (not with class constructions). Replace *args by immutable list (Tuple[a,Tuple[b, ...) when ParamSpec fails to scale.  Replace **kwargs with object using @overload  with Literal typed arguments (sadly TypedDict seems not to support generic typing) . Use Generic to “store” multiple polymorphic types Use Protocol to separate semantic tiers of types (e.g. ownership in a smart contract) No nested functions, lambdas or classes. Use cast to type "unmanaged" types (e.g. eval) Use phantom typed "dummy" arguments (and type casts) to get around "wrong direction" type dependencies Visual Code's Pyright works. Early 2021, pycharm fails. The untyped application scope is a broader Python 3 stack. Note this is 3.10 Python typing (e.g. Par...