A functional, array-oriented, tacit programming esolang run via Python interpreter
Project description
WARNING: GUIDO VON ROSSUM WILL HATE YOU. DON'T USE THIS IN PRODUCTION CODE OR YOU'LL BE FIRED.
Iterlingua
An array-oriented tacit functional dialect for Python, inspired by APL/J.
Introduction
Iterlingua is a domain-specific language (DSL) that brings array-oriented and tacit (point-free) programming to Python. It provides a concise syntax for array manipulation, function composition, and higher-order functions.
- If you don't even know what
tacitmeans, or you haven't used an array-oriented language before, Iterlingua is not for you.
Installation
pip install iterlingua
Iterlingua is a pure Python package, with no dependencies.
It's also compatible with MicroPython on CASIO calculators. If you want to use it on a CASIO calculator (fx-CG50 or fx-9860GIII), download the __init__.py file, rename it to iterlingua.py, and drag it into the calculator.
Quick Start
from iterlingua import *
# Basic usage
print(o("Hello World").o) # "Hello World" | Wrap & unwrap
print(o(27)[mul, 3].o) # 81 | Function application
print(o(27)[mul, 3][add, 1][div, 2].o) # 41 | Pipeline
# Array operations and pipelines
a = [ 1, 2, 3]
b = [10,20,30]
print(o(a)(0)[mul, 3][add, 1][div, 2]().o) # [2.0, 3.5, 5.0] | (0) means adding rank -> automatic broadcast
element_wise = o(a)(0)[add, o(b)(0)].o # Same rank -> Apply function element-wise
print(element_wise) # [11, 22, 33]
cartesian = o(a)(1)[add, o(b)(0)]()().o # Different rank -> Cartesian product
print(cartesian) # [[11,12,13],[21,22,23],[31,32,33]]
# Function composition
flatten = fixedpoint(ravel) # Flatten nested arrays
average = train(reduce(add),div,len) # Calculate average
l = [[3,1],[4,[1,5]],[[9,2],6]]
flat = flatten(l); print(flat) # [3, 1, 4, 1, 5, 9, 2, 6]
avg = average(flat); print(avg) # 3.875
Core Concepts
1. The Rank System
The Rank System is the core mechanism of this language, deeply inspired by APL (but in APL "rank" means "depth" instead, which is different from our definition), designed to control how functions iterate over nested lists (arrays) without writing explicit loops. It separates the shape of the data from the logic of the function.
Here is a breakdown of how it works:
The Core Idea: Depth and Iteration
In Python, a 2D list like [[1, 2], [3, 4]] has a depth of 2. If you want to add a scalar 10 to every inner number, you have to write nested loops.
The Rank system allows you to tell a function: "Treat this data as a collection of sub-arrays at a specific depth, and apply the function to each sub-array independently."
- If you've known any array-oriented languages before -- Iterlingua is different! It doesn't broadcast automatically.
The _it Wrapper and Rank Tracking
Under the hood, array data is, internally, wrapped in a special _it object.
An _it object stores two things:
l: The actual data (e.g.,[[1, 2], [3, 4]])r: A list of integers representing the Rank (e.g.,[0, 1]) The rank listrspecifies at when the function should stop descending and apply itself.
How Applying with Rank Works
When you execute a function via obj[func, other_data](will explain later), it calls the internal _f function. _f looks at the rank lists of all arguments and orchestrates the iterations. Here's how it works:
Imagine this process as a package sorting system. Inside _f there is the sorter, and the ranks are the input belts. Each round, _f looks at the current lowest rank, and accepts all elements with that rank. The rank information is preserved.
Once the sorter establishes this unified traversal route, another inner function takes over to execute the actual data extraction. It navigates through the nested lists strictly following the predefined route. At each dimension step:
- Arguments that are marked as "active" for the current dimension advance one level deeper into their nested lists.
- Arguments that are inactive at this dimension remain untouched, effectively broadcasting their current value to every element extracted from the active arguments.
- The recursion continues until all predefined dimensions are exhausted. At the very bottom level, the target function
fis finally applied to the collected scalar values.
Finally, the collected results are assembled back into a new nested list, tagged with the newly sorted dimension sequence, and wrapped as a fresh _it object.
Example A: Element-Wise Operation (Matching Ranks)
a = o([1, 2, 3])(0) # _it([1,2,3], [0])
b = o([10,20,30])(0) # _it([10,20,30], [0])
a[add, b]
- Both have rank
[0]. _fsees rank 0: it iterates through the outer list, pulling out scalars.- Executes
add(1, 10),add(2, 20),add(3, 30). - Result:
[11, 22, 33]with rank[0]. Example B: Broadcasting / Cartesian Product (Mismatched Ranks)
a = o([[1, 2], [3, 4]])(0, 1) # 2D array, ranks 0 and 1
b = o([10, 20])(1) # 1D array, rank 1
a[add, b]
_fprocesses ranks from shallowest to deepest.- Rank 1: Iterates over the outer layer.
ayields[1,2]and[3,4];byields10and20. - Rank 0: Iterates over the inner layer for each pair.
- Executes
add(1, 10),add(2, 10), thenadd(3, 20),add(4, 20). - Result:
[[11, 12], [23, 24]]with rank[0, 1].
Padding with placeholders (The Size Mismatch Rule)
If arrays at a given rank have different lengths, the system uses the first argument's size as the master size.
If a shorter array runs out of elements, a special _it placeholder object is inserted. When the function is finally called with a placeholder, the system immediately returns the other argument's element unchanged (as dictated by the rule: _it in b -> return b[0]). This intentionally creates jagged padding behavior rather than implicit zip-truncation or erroring.
2. The o Wrapper
The o wrapper is the primary interface for creating rank-aware data objects. It wraps Python data (lists, scalars, etc.) into an Iterlingua object that tracks rank information.
Basic Wrapping
# Wrap a list, in this case you don't need the square brackets.
o([1, 2, 3]) # o(1, 2, 3) does the same.
# Wrap a scalar
o(42)
# Wrap nested lists
o([[1, 2], [3, 4]])
Setting Rank with ()
The () operator sets the rank for the wrapped data:
o([1, 2, 3])(0) # Rank [0]
o([1, 2, 3])(1) # Rank [1]
o([[1, 2], [3, 4]])(0, 1) # Ranks [0, 1] - iterate at both levels
Multiple () calls add ranks to the list:
o([1, 2, 3])(0)(1) # Ranks [0, 1]
Unwrapping with ()
Calling () without arguments unwraps the result, removing one level of rank tracking:
result = o([1, 2, 3])(0)[add, 10]() # Unwraps to [11, 12, 13]
The .o Attribute
Access the underlying data with .o:
wrapped = o([1, 2, 3])
data = wrapped.o # [1, 2, 3]
Chaining Operations
The power of o comes from chaining operations:
o(1, 2, 3)(0)[mul, 3][add, 1][div, 2]()
# Step 1: [1, 2, 3] * 3 = [3, 6, 9]
# Step 2: [3, 6, 9] + 1 = [4, 7, 10]
# Step 3: [4, 7, 10] / 2 = [2, 3.5, 5]
This is where the rank system comes into play:
o(1, 2, 3)(0)[add, o([10, 20, 30])(0)]() # [11, 22, 33]
o(1, 2)(0)[add, o([10, 20])(1)]()() # [[11, 21], [12, 22]]
o([1,2],[3,4])(0,1)[add, 1]()() # [[2, 3], [4, 5]]
3. The c Composition Operator
The c operator enables tacit (point-free) programming by composing functions without explicitly naming arguments.
Basic Composition
Think c as a o-wrapped object and perform operations on it. Use a .f to retrieve the underlying function.
# Create a function that adds 1
add_one = c[add, 1].f
add_one(5) # 6
# Create a function that multiplies by 2
double = c[mul, 2].f
double(5) # 10
# Chaining
process = c[add, 1][mul, 2][sub, 3].f
process(5) # ((5 + 1) * 2) - 3 = 9
4. The arg Argument Reference System
For more complex tacit expressions, Iterlingua provides argument reference objects that let you refer to arguments positionally.
Available References
| Object | Meaning | Index | |
|---|---|---|---|
ai |
First argument | 0 (left) | |
wi |
Second argument | 1 (leftmost right) | |
recur |
Self-reference (recursion) | -1 (function) | |
arg(n) |
nth argument | n |
Accessing Argument Properties
# ai refers to the first argument
square = c[mul, ai].f
square(5) # 25
# wi refers to the second argument
multiply_by_second = c[mul, wi].f
multiply_by_second(5, 3) # 15
Transforming Arguments
You can treat arguments, again, as o-wrapped objects.
# Double the second argument, then add the first
complex_op = c[add, wi[mul, 2]].f
complex_op(5, 3) # 5 + (3 * 2) = 11
Recursion with recur
The recur reference allows recursive definitions:
# Factorial using recursion
factorial = c[sub,1][cond,c[gt, 1],recur,const(1)][mul,ai].f
factorial(5) # 120
# Note: this is way more efficient
factorial_iterative = c[lrange](0)[add,1]()[reduce(mul)].f
Referring to the nth argument
ai is actually an alias for arg(0), and wi is an alias for arg(1). To refer to the nth argument, use arg(n).
mapnum = c[sub,arg(1)][div,arg(1)[sub,arg(2)]][mul,arg(3)[sub,arg(4)]][add,arg(3)].f
celsius = 26
fahrenheit = mapnum(celsius, 0, 100, 32, 212) # 78.8
5. Function Trains, and other higher-order functions
A train is a way to compose functions in a fork-like pattern, inspired by APL/J language. Iterlingua also provides several higher-order functions that work seamlessly with the rank system.
- These functions automatically adds
.fto compositions, so you don't need to explicitly call.f.
The train Function
# train(left, middle, right) creates: middle(left(x), right(x))
average = train(reduce(add), div, len)
average([1, 2, 3, 4, 5]) # sum / len = 3.0
reduce - Left Fold
# Reduce with a binary function
reduce(add)([1, 2, 3, 4]) # 10
reduce(mul)([1, 2, 3, 4]) # 24
# With initial value
reduce(add, 10)([1, 2, 3]) # 16
# also see inline reduce
ireduce([1, 2, 3, 4], add, 0) # 10
prefix - Cumulative Scan
# Running totals
prefix(add)([1, 2, 3, 4]) # [1, 3, 6, 10]
prefix(mul)([1, 2, 3, 4]) # [1, 2, 6, 24]
# Initial value like reduce
prefix(add, 10)([1, 2, 3]) # [11, 13, 16]
filter - Predicate Filtering
# Keep elements matching a condition
filter(c[gt, 3])([1, 5, 2, 8, 3]) # [5, 8]
filter(c[lt, 5])([1, 5, 2, 8, 3]) # [1, 2, 3]
fixedpoint - Iterate Until Stable
# Keep applying until result doesn't change
flatten = fixedpoint(ravel)
flatten([[1, [2, 3]], [[4]]]) # [1, 2, 3, 4]
until - Iterate Until Condition
# Double until greater than 10
until(1, c[mul, 2], c[gt, 10]) # 16
repeat - Apply N Times
# Apply negation 3 times
repeat(neg)(5, 3) # -5 (odd number of negations)
repeat(neg)(5, 4) # 5 (even number of negations)
6. Other useful functions
HOF Helpers
const - Constant Function
# Create a constant function that returns 10 (K combinator)
const(10)(5) # 10
tack() - Identity Function
# Create a function that returns the first argument (I combinator generator)
tack()(5) # 5
# Also can return the second argument
tack(1)("1st","2nd") # "2nd"
cond - Conditional Application
# cond(value, condition, if_true, if_false)
collatz_step = c[cond,c[mod,2][eq,0],c[div,2],c[mul,3][add,1]].f
splt - Apply Multiple Functions
# Apply different functions to each element
splt([1, 2, 3], neg, c[mul, 2], c[add, 10]) # [-1, 4, 13]
slide - Sliding Window Operation
# Apply a function to each sliding window of size 2
slide([1, 2, 3, 4, 5], 2, add) # [3, 5, 7, 9]
Debugging
Common problems
1. Compositions returning objects instead of values (Missing .f or _o)
When passing a composition (c[...]) or wrapped object (o[...]) into some functions, if the receiving function doesn't unpack it, it won't do what you expect correctly, or even worse, it will throw a TypeError. Use @adaptIterlingua to automatically unpack the arguments.
# BAD: splt doesn't automatically unpack c[...], so it returns a wrong result
def my_func(f, x):
return f(x)
my_func(c[mul, 2], [1, 2]) # -> <_c object>
# SOLUTION: extract the function with .f first
my_func(c[mul, 2].f, [1, 2]) # -> [2, 4]
# GOOD: use adaptIterlingua decorator
@adaptIterlingua
def my_func(f, x):
return f(x)
my_func(c[mul, 2], [1, 2]) # -> [2, 4]
Note: Iterlingua builtin functions like filter, reduce, and train automatically handle _c objects.
2. Silent padding with rank mismatches
If you combine arrays of different lengths, the system does not throw an error or truncate. It pads the shorter array with placeholders, which cause the function to simply return the other argument's element unchanged.
o([1, 2, 3])(0)[add, o([10])(0)].o
# Expected: [11] or Error
# Actual: [11, 2, 3] (Because add(2, placeholder) just returns 2)
Always check your array lengths if your results seem to be missing an operation.
3. Mixing up Rank setting () and Function application []
Because Python's syntax is overloaded, it's easy to mix up when to use parentheses and when to use brackets.
()on anoobject adds rank or unwraps:o([1,2])(0)[]on anoobject applies a function:o([1,2])[add, 1]- Calling
o([1,2])(add, 1)will try to set the ranks to[add, 1], which will cause it to crash.
4. Forgetting to unwrap the final result
Chaining operations keeps data wrapped in the o or _c objects. If you try to pass the result to standard Python functions (like print or len), it will fail or print the wrapper object.
- Use
.oto get the raw Python list/value from anochain. - Use
.fto get the callable Python function from acchain.
iprint - Print and Return
Iterlingua provides iprint to allow you to print debug information while preserving the original value.
iprint(1, 2, 3) # prints "123" and returns 1
- Be careful with arrays with ranks, as they'll be broadcasted automatically.
iterlingua.debug - Debugging Tool
- The following contents are not supported on CASIO calculators, and an ANSI-supporting console is required.
Instead of using
from iterlingua import *, dofrom iterlingua.debug import *. This replaces theowrapper with an animated version that visualizes every step of the rank system in your terminal.
from iterlingua.debug import *
o([1, 2, 3])(0)[add, 10]()
Each step is rendered as an ASCII tree showing the internal structure, then erased before the next step appears — creating a flipbook animation of how your data flows through the pipeline.
How to Read the Visualization
The debug renderer shows your data as a tree. Each node displays:
d0,d1, etc. — the rank at that level. This tells you that this element is not treated as a scalar.>— a horizontal list of elements.v— a vertical list of elements (used when nesting forces a layout break). For example,o([1, 2, 3])(0)renders as:
d0-> 1 2 3
And o([[1, 2], [3, 4]])(0, 1) renders as:
d0-> d1 d1
v v
1 3
2 4
Controlling the Animation
# Slow down the animation (default is 0.3 seconds per step)
from time import sleep
setAnimateDelay(lambda: sleep(0.5))
# Speed up
setAnimateDelay(lambda: sleep(0.1))
# Disable animation entirely (just pretty-print the final result)
setAnimateDelay(None)
When to Use It
- Rank confusion: If your broadcasting doesn't produce the shape you expected, watch the animation to see exactly which depth the system is iterating at and where padding kicks in.
- Composition debugging: Step through
c[...]chains to see how arguments flow through each stage. - Understanding the rank system: The best way to learn — just try expressions and watch what happens.
Reading the Error Messages
Iterlingua doesn't throw custom errors — it relies on Python's native exceptions. Because of the heavy operator overloading, the error messages can be misleading. Remember, look at what's on the top of the Traceback first -- That's where the error occurs. Then you should look at the bottom -- here are the types you'll see most often and what they most likely mean:
| Message | Meaning |
|---|---|
TypeError: '<' not supported between instances of 'function' and 'function' |
You probably confused ...[x] with ...(x). |
TypeError: <func> takes N positional arguments but M were given |
You're literally passing the wrong number of arguments to the function. Most probably in c and train. |
TypeError: 'int' object is not callable |
This is either because you forgot to wrap your data with o, or you confused ...(x) with ...[x]. |
TypeError: 'type' object is not subscriptable |
You wrote o[...] instead of o(...). Square brackets on o mean function application via __getitem__, not construction. |
TypeError: object of type <type> has no len() |
You added a rank to a scalar by mistake. |
IndexError: list index out of range |
Either you're trying to access an element that doesn't exist in the array, or you fed wrong number of arguments to the tack(x) or splt function. |
ZeroDivisionError: integer division or modulo by zero |
Either you're literally dividing by zero, or you passed an empty array to trimroll. |
StopIteration |
You passed an empty array to a reduce(...) without a start value. |
Design Philosophy
Iterlingua exists for only one reason: I wanted to write APL on that poor CASIO calculator.
Not to make Python better. I just wanted to write that way—to compress a whole data pipeline into a single line of symbols and watch it flow.
Python doesn't let you do that. So I made a dialect that does. This leads to some un-Pythonic choices. I'm not apologizing for them, but I won't pretend they're accidental either:
- Silent Padding
In APL, when you apply a function to arrays of different ranks, it just raises an error. In Python (using
zip), it just truncates the longer array. I dislike both, so I designed this silent padding feature. - You Set Rank Yourself In both APL and NumPy, the broadcast mechanism is automatically inferred. As the Zen of Python wrote, "Explicit is better than implicit", I prefer to declare the rank explicitly.
- Operators Are Functions
In both APL and Python, the operators are symbols. In APL, they are functions. In Python, they are syntax. But, APL operators do too much things, and Python's operators aren't functions (this is the limit). So, the
+operator is written asadd. - Tacit / Point-Free by Default
APL doesn't make you name arguments if you don't want to. You just compose functions and let the data flow through. Python forces you to say
lambda x: x + 1. Iterlingua lets you sayc[add, 1].f-- nox, nolambda, no noise. Thecwrapper exists purely so you can build functions without ever mentioning their inputs. - Chain or Die
Everything returns a wrapper, everything chains. There's no "oh, this returns a raw list so I need to wrap it again."
o([1,2,3])(0)[add, 1][mul, 2]().ois one breath. The.oat the end is actually not required if you're not chaining, but if you forget it when returning to Python, you deserve what you get.
If these choices make you uncomfortable, Iterlingua is probably not for you. That's fine -- Python is already an excellent language.
Performance
Iterlingua is actually slow, despite the fact that I've tried my best to optimize it.
Every [func, arg] operation traverses nested lists recursively. There is no lazy evaluation, no C extensions, no JIT. On a CASIO calculator, this doesn't matter. On a server processing million-element arrays, it matters a lot.
| What you're doing | What you should use |
|---|---|
| < 1,000 elements, nested lists, exploring ideas | Iterlingua is fine |
| Heavy numeric computation, large matrices | NumPy or JAX |
| Production data pipelines | Pandas or Polars |
| CASIO calculator / no install rights | Iterlingua is just the right tool |
Why not make it faster?
Two reasons:
- I wanted to write APL, not a compiler. Making Iterlingua fast would require either a complete rewrite in C (now it's NumPy) or a JIT compiler (now it's JAX). At that point it's not a hack anymore -- it's a job.
- The CASIO constraint. If I can't fit the source in my head and the runtime in 60KB of RAM, I've lost the plot.
If you're measuring performance, you're already using the wrong tool.
API Reference
Operators' Aliases
| Operator | Name | Operator | Name |
|---|---|---|---|
x+y |
add |
x-y |
sub |
x*y |
mul |
x/y |
div |
x//y |
floordiv |
x%y |
mod |
-x |
neg |
x<y |
lt |
x>y |
gt |
x<=y |
le |
x>=y |
ge |
x==y |
eq |
x!=y |
ne |
x or y |
lor |
x and y |
land |
not x |
lnot |
x|y |
bor |
x&y |
band |
x^y |
bxor |
x<<y |
bshl |
x>>y |
bshr |
x[y] |
get |
x[y:z] |
slice |
x[:y] |
take |
x[y:] |
drop |
x in y |
inside |
Array Construction
| Function | Description | Example |
|---|---|---|
clist |
Coerce to list | clist((1,2)) -> [1,2] |
lrange |
list(range(*a)) |
lrange(1,5) -> [1,2,3,4] |
enclose |
Wrap in list | enclose(3) -> [3] |
Array Trimming & Padding
| Function | Description | Example |
|---|---|---|
trimwhile |
Trim from end while condition holds | trimwhile([1,2,0,0],eq(0)) -> [1,2] |
trimroll |
Trim or roll to fill length | trimroll([1,2],5) -> [1,2,1,2,1] |
trimfill |
Trim or fill to length | trimfill([1,2],4,0) -> [1,2,0,0] |
padto |
Pad to length (doesn't trim) | padto([1,2],4,0) -> [1,2,0,0] |
Array Restructuring
| Function | Description | Example |
|---|---|---|
reverse |
Reverse | reverse([1,2,3]) -> [3,2,1] |
rotate |
Circular shift | rotate([1,2,3,4],1) -> [4,1,2,3] |
ravel |
Flatten one level | ravel([[1,2],[3]]) -> [1,2,3] |
zip |
Transpose (no truncation) | zip([[1,2],[3,4]]) -> [[1,3],[2,4]] |
regroup |
Group by fixed size | regroup([1,2,3,4],2) -> [[1,2],[3,4]] |
window |
Sliding windows | window([1,2,3,4],3) -> [[1,2,3],[2,3,4]] |
splice |
Replace slice | splice([1,2,3,4],1,3,[9]) -> [1,9,4] |
amend |
Replace at index | amend([1,2,3],1,9) -> [1,9,3] |
sortk |
Sort by key function | sortk(['bb','a'],len) -> ['a','bb'] |
Array Selection & Search
| Function | Description | Example |
|---|---|---|
grade |
Indices that would sort | grade([3,1,4]) -> [1,0,2] |
dgrade |
Duplicative ranking | dgrade([3,1,4,1]) -> [2,0,3,0] |
indexes |
Indices of matching items | indexes([1,2,1],1) -> [0,2] |
find |
Find sublist positions | find([1,2,3,2,3],[2,3]) -> [1,3] |
filter(f) |
Filter by predicate | filter(c[gt,3])([1,5,2]) -> [5] |
compress |
Keep items where mask is truthy | compress([1,2,3],[1,0,1]) -> [1,3] |
unique |
Remove duplicates (first occurrence) | unique([1,2,1,3]) -> [1,2,3] |
Array Partitioning & Grouping
| Function | Description | Example |
|---|---|---|
rpartition |
Partition by adjacent equal keys | rpartition([1,1,2],[1,1,2]) -> [[1,1],[2]] |
spartition |
Group by key (sorted) | spartition([1,2,3],[1,2,1]) -> [[1,3],[2]] |
runlen |
Run-length encoding | runlen([1,1,2,2,2]) -> [2,3] |
runsqz |
Squeeze adjacent duplicates | runsqz([1,1,2,2,1]) -> [1,2,1] |
Functional Programming
| Function | Description | Example |
|---|---|---|
apply |
Apply function to unpacked tuple | apply((3,5),add) -> 8 |
cond |
Conditional apply | cond(5,c[gt,3],neg) -> -5 |
commute(f,idx) |
Swap arg 0 and arg idx | commute(sub)(5,3) -> -2 |
revf(f) |
Apply f to reversed, then reverse | revf(window)([1,2,3],2) -> [[3,2],[2,1]] |
splt |
Apply each function to each element | splt([1,2],neg,enclose) -> [-1,[2]] |
Higher-Order Functions & Helpers
| Function | Description | Example |
|---|---|---|
reduce(f,[start]) |
Left fold | reduce(add)([1,2,3]) -> 6 |
prefix(f,[start]) |
Cumulative scan | prefix(add)([1,2,3]) -> [1,3,6] |
ireduce |
Reduce with initial value (swapped) | ireduce([1,2,3],add,0) -> 6 |
repeat(f)(x,n,...) |
Apply f n times | repeat(neg)(5,2) -> 5 |
until(v,f,t) |
Apply f until t(v) is true | until(1,c[mul,2],c[gt,10]) -> 16 |
fixedpoint(f,limit) |
Iterate until stable | fixedpoint(sorted)([3,1,2]) -> [1,2,3] |
slide |
Apply f to sliding windows | slide([1,2,3],2,add) -> [3,5] |
train(lf,mf,*rf) |
Fork train | train(sum,div,len)([1,2,3]) -> 2 |
const(x) |
Return constant function | const(5)(9) -> 5 |
tack(n) |
Return nth argument function | tack(1)(7,8) -> 8 |
License
Iterlingua is licensed under the Unlicense.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file iterlingua-0.1.0.tar.gz.
File metadata
- Download URL: iterlingua-0.1.0.tar.gz
- Upload date:
- Size: 28.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a96966effb894c212f2779549c8c45945abbc7608e9b4a490dddbf997a9e4d9a
|
|
| MD5 |
4c9476a32095f47962d0a22eb83f2bed
|
|
| BLAKE2b-256 |
599345fa6e669e60d1b79320f6e42038025d3f57136dbb20e25a3e857a49b16d
|
File details
Details for the file iterlingua-0.1.0-py3-none-any.whl.
File metadata
- Download URL: iterlingua-0.1.0-py3-none-any.whl
- Upload date:
- Size: 18.3 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
c24b9815513a6b03f9e5b214e8c77f658ad19bb4244d8a98ff9fac0ae02c32a0
|
|
| MD5 |
ed0ad942739747cb0c30697a74b75bc3
|
|
| BLAKE2b-256 |
28ad3d89ca771dc06f41ba3b01939e5a153148be54a4ca14b8d1503295116323
|