Strings¶
String code checks in strict mode and is proven pure, but it stays on
CPython, and the compiler says so. String methods are fully typed
(name.split(" ") is a list[str], part[0].upper() a str). A Python
string has no native representation, though, so these functions run as
ordinary Python on every path.
Run it¶
What it prints¶
python strings.ppy, ppy strings.ppy, ppy run strings.ppy
Typed, checked, not lowered¶
@ppy.pure
def is_palindrome(text: str) -> bool:
cleaned: str = text.lower().replace(" ", "")
left: int = 0
right: int = len(cleaned) - 1
while left < right:
if cleaned[left] != cleaned[right]:
return False
left += 1
right -= 1
return True
The loop is native-shaped, but cleaned[left] indexes a str. The checker
proves the function pure, and it stays on the Python side.
ppy explain strings.ppy:is_palindrome reports the first construct that
blocked lowering.
Fast text goes through bytes¶
Text that needs to be fast goes through a byte buffer instead.
Buffer[ppy.u8] is one byte per character and lowers, which is how
substring search scans four million
characters natively.
Where the code comes from¶
strings.ppy is hand-written; there is no .py source and no conversion step.
Read on: Reading input · Native lowering · Algorithms: substring search
19_strings/strings.ppy¶
import ppy
@ppy.pure
def initials(name: str) -> str:
out: str = ""
for part in name.split(" "):
if len(part) > 0:
out += part[0].upper()
return out
@ppy.pure
def is_palindrome(text: str) -> bool:
cleaned: str = text.lower().replace(" ", "")
left: int = 0
right: int = len(cleaned) - 1
while left < right:
if cleaned[left] != cleaned[right]:
return False
left += 1
right -= 1
return True
@ppy.pure
def word_count(text: str) -> dict[str, int]:
counts: dict[str, int] = {}
for word in text.lower().split(" "):
counts[word] = counts.get(word, 0) + 1
return counts
def main() -> None:
print(initials("ada lovelace king"))
print(is_palindrome("A man a plan a canal Panama"), is_palindrome("nope"))
print(sorted(word_count("a b a c b a").items()))
main()
Source: examples/19_strings.