Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Windows Tipps & SecurityGarmin Cirqa im Test: Fitness-Tracker ohne Display(22.09.2026 um 10:30 Uhr)
Windows Tipps & SecuritySicher online bezahlen: 7 Methoden im Praxis-Check(22.09.2026 um 09:00 Uhr)
Sichere Programmierunghas_tokens: true is a boolean. 476 of 791 have no market behind them.(22.09.2026 um 10:00 Uhr)
Sichere ProgrammierungClaude Code Hooks – Safety Through Invariants(22.09.2026 um 10:04 Uhr)
Sichere ProgrammierungYour MCP Tool Just Returned a Secret. Did It Need To?(22.09.2026 um 10:05 Uhr)
Windows Tipps & SecurityGarmin Cirqa im Test: Fitness-Tracker ohne Display(22.09.2026 um 10:30 Uhr)
Windows Tipps & SecuritySicher online bezahlen: 7 Methoden im Praxis-Check(22.09.2026 um 09:00 Uhr)
Sichere Programmierunghas_tokens: true is a boolean. 476 of 791 have no market behind them.(22.09.2026 um 10:00 Uhr)
Sichere ProgrammierungClaude Code Hooks – Safety Through Invariants(22.09.2026 um 10:04 Uhr)
Sichere ProgrammierungYour MCP Tool Just Returned a Secret. Did It Need To?(22.09.2026 um 10:05 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Python to Wisp: The Lisp That Stole Python's Indentation

Python to Wisp: The Lisp That Stole Python's Indentation Every Lisp programmer has heard the complaint: "too many parentheses." Every Python programmer has heard the praise: "the indentation makes it readable." Wisp asks a dangerous…

0
↗ Quelle (dev.to)
Reagiere als Erste:r — dein Feedback zählt!




Python to Wisp: The Lisp That Stole Python's Indentation



Every Lisp programmer has heard the complaint: "too many parentheses." Every Python programmer has heard the praise: "the indentation makes it readable." Wisp asks a dangerous question: what if we put them together?



Wisp is an indentation-sensitive syntax for Scheme — specifically GNU Guile Scheme — standardized as SRFI-119. It takes the structure of Lisp and expresses it through indentation, the way Python does. The outer parentheses vanish. What remains is code that looks strangely like Python but thinks like Lisp — with macros, tail-call optimization, exact arithmetic, and homoiconicity.



This article walks through every major topic in the official Python tutorial and shows how Wisp approaches the same concept. Two languages, both indented, separated by philosophy.









1. Whetting Your Appetite



Python sells itself on readability, rapid prototyping, and an enormous ecosystem. It's the default choice for scripts, web backends, data science, and teaching.



Wisp sells itself on a different proposition: the readability of Python's visual structure combined with the raw power of Scheme. Scheme is one of the most theoretically clean programming languages ever designed — tail-call optimization, first-class continuations, hygienic macros — but its parenthesized syntax scares newcomers away. Wisp removes that barrier.



Wisp runs on GNU Guile, a mature Scheme implementation that ships with many GNU/Linux distributions. It gives you access to Guile's full ecosystem: real OS threads (no GIL), arbitrary-precision arithmetic, a sophisticated module system, and the ability to reshape the language through macros.



The trade-off? Python has PyPI. Wisp has the Guile ecosystem and whatever you can call via FFI. This isn't a contest for library count — it's a contest for expressiveness per line.









2. The Interpreter / The REPL



Python:




>>> 2 + 2
4
>>> print("Hello, world!")
Hello, world!






Wisp:




> + 2 2
4
> display "Hello, world!"
Hello, world!






To use Wisp interactively, launch guile and switch languages with ,L wisp. Or run scripts directly: guile --language=wisp -s hello.w.



The syntax is prefix notation — the function comes first, then its arguments — but without the outer parentheses that traditional Scheme requires. The line display "Hello, world!" is equivalent to Scheme's (display "Hello, world!"). Indentation replaces the parens.









3. An Informal Introduction






Numbers



Python:




>>> 17 / 3       # 5.666...
>>> 17 // 3 # 5
>>> 17 % 3 # 2
>>> 5 ** 2 # 25






Wisp:




/ 17 3            ; 17/3 — an exact rational!
quotient 17 3 ; 5
remainder 17 3 ; 2
expt 5 2 ; 25






The first difference is striking. (/ 17 3) in Scheme returns 17/3 — an exact rational number, not a floating-point approximation. Scheme distinguishes exact and inexact numbers at the type level. If you want the float, you ask for it explicitly: (exact->inexact (/ 17 3)) gives 5.666....



Operators take multiple arguments naturally:




+ 1 2 3 4 5       ; 15
* 2 3 4 ; 24
< 1 2 3 4 ; #t (chained comparison)






And Scheme gives you arbitrary-precision integers for free. No int vs long distinction, no overflow:




expt 2 1000        ; a 302-digit number, exactly









Strings



Python:




word = "Python"
word[0] # 'P'
word[0:2] # 'Py'
len(word) # 6
f"Hello, {word}!"






Wisp:




define word "Wisp"
string-ref word 0 ; #\W (a character)
substring word 0 2 ; "Wi"
string-length word ; 4
format #f "Hello, ~a!" word ; "Hello, Wisp!"






Scheme strings are mutable (unlike Python's), though idiomatic Scheme treats them as values. The format function uses ~a as a placeholder — #f means "return a string" and #t means "print directly":




format #t "Hello, ~a!\n" word   ; prints: Hello, Wisp!









Lists



Python:




squares = [1, 4, 9, 16, 25]
squares[0] # 1
squares + [36, 49] # [1, 4, 9, 16, 25, 36, 49]
squares.append(36) # mutates!






Wisp:




define squares '(1 4 9 16 25)
list-ref squares 0 ; 1
append squares '(36 49) ; (1 4 9 16 25 36 49)






Scheme lists are linked lists — immutable by convention, efficient at the head. append returns a new list without modifying the original. There's no .append mutation. If you want indexed access, Scheme has vectors:




define sq #(1 4 9 16 25)
vector-ref sq 0 ; 1






The '(1 4 9 16 25) is a quoted list — the quote ' prevents Scheme from trying to call 1 as a function.









4. Control Flow






if / cond



Python:




if x < 0:
print("Negative")
elif x == 0:
print("Zero")
else:
print("Positive")






Wisp:




cond
: < x 0
display "Negative"
: = x 0
display "Zero"
else
display "Positive"






In Wisp, cond handles multi-branch conditionals. Each branch starts with a : (which creates the nested parentheses Scheme expects). The else clause catches everything.



The simple if takes a condition, a then-branch, and an else-branch:




if : < x 0
display "Negative"
display "Non-negative"






And because if is an expression, not a statement, you can use it anywhere:




define label
if : < x 0
. "negative"
. "non-negative"






The . (dot) prevents the string from being treated as a function call — it marks a bare value rather than an application.






for loops



Python:




for word in ["cat", "window", "defenestrate"]:
print(word, len(word))






Wisp:




for-each
lambda : word
display word
display " "
display : string-length word
newline
'("cat" "window" "defenestrate")






Scheme doesn't have a built-in for loop — iteration is done through for-each (for side effects) or map (for transformation). The lambda defines an anonymous function applied to each element.



Or using a named let (Scheme's idiomatic loop):




let loop
: words '("cat" "window" "defenestrate")
when : not : null? words
display : car words
display " "
display : string-length : car words
newline
loop : cdr words






This is recursion that looks like a loop. car gets the first element, cdr gets the rest, and loop calls itself with the remaining list. Guile guarantees tail-call optimization, so this uses constant stack space — unlike Python, which would hit a recursion limit.






range



Python:




list(range(0, 10, 2))  # [0, 2, 4, 6, 8]






Wisp:




use-modules : srfi srfi-1

iota 5 0 2 ; (0 2 4 6 8)






Guile's iota from SRFI-1 generates numeric sequences. The arguments are count, start, and step — slightly different from Python's start, stop, step.






while



Python:




a, b = 0, 1
while a < 10:
print(a)
a, b = b, a + b






Wisp:




let loop : : a 0
b 1
when : < a 10
display a
newline
loop b {a + b}






There's no while keyword here — it's a named let that recurses. The {a + b} uses Wisp's curly-brace infix syntax (from SRFI-105), which lets you write math the familiar way. Without it, you'd write (+ a b).






Pattern Matching



Python 3.10+:




match command:
case "quit":
quit_game()
case "help":
show_help()
case _:
print("Unknown")






Wisp (using Guile's match):




use-modules : ice-9 match

match command
: "quit"
quit-game
: "help"
show-help
: _
display "Unknown"






Guile's match supports destructuring, guards, and nested patterns — similar to Python's structural pattern matching but available since long before Python 3.10.






Functions



Python:




def factorial(n):
"""Return the factorial of n."""
if n == 0:
return 1
return n * factorial(n - 1)






Wisp:




define : factorial n
"Return the factorial of n."
if : = n 0
. 1
* n : factorial {n - 1}






Functions are defined with define. The : factorial n creates (factorial n) — a function named factorial taking one argument. The docstring goes right after the parameter list. The last expression is the return value.



The Wisp version also benefits from tail-call optimization if rewritten in tail-recursive style:




define : factorial n
let loop : : i n
acc 1
if : = i 0
. acc
loop {i - 1} {acc * i}






This handles (factorial 100000) without breaking a sweat. Python would need sys.setrecursionlimit or an iterative rewrite.






Default and Keyword Arguments



Python:




def greet(name, greeting="Hello"):
print(f"{greeting}, {name}!")






Wisp:




use-modules : ice-9 optargs

define* : greet name #:optional (greeting "Hello")
format #t "~a, ~a!\n" greeting name






Guile uses define* (from ice-9 optargs) for optional and keyword arguments:




define* : connect host #:key (port 8080) (timeout 30)
format #t "Connecting to ~a:~a (timeout ~a)\n" host port timeout

connect "example.com" #:port 443
; => Connecting to example.com:443 (timeout 30)






#:optional for positional defaults, #:key for keyword arguments. More explicit than Python's unified syntax, but equally capable.






Lambda Expressions



Python:




double = lambda x: x * 2
sorted(words, key=lambda w: len(w))






Wisp:




define double
lambda : x
* x 2

sort words
lambda : a b
< (string-length a) (string-length b)






In Wisp, lambda is a full block — no single-expression restriction like Python's lambda. The indented body can contain anything.









5. Data Structures






Lists (Linked Lists)



Scheme lists are cons-cell linked lists — the fundamental data structure of all Lisps:




define fruits '("apple" "banana" "cherry")
car fruits ; "apple" (first)
cdr fruits ; ("banana" "cherry") (rest)
cons "mango" fruits ; ("mango" "apple" "banana" "cherry")
length fruits ; 3
list-ref fruits 1 ; "banana"














































Operation Python Wisp
First element lst[0] car lst
Rest of list lst[1:] cdr lst
Prepend [x] + lst cons x lst
Append lst + [x] append lst (list x)
Length len(lst) length lst
Nth element lst[n] list-ref lst n





Vectors (Arrays)



For indexed access, Scheme has vectors:




define v #(10 20 30 40 50)
vector-ref v 2 ; 30
vector-length v ; 5









Hash Tables (Dictionaries)



Python:




tel = {"jack": 4098, "sape": 4139}
tel["guido"] = 4127
del tel["sape"]






Wisp:




define tel : make-hash-table

hashq-set! tel 'jack 4098
hashq-set! tel 'sape 4139
hashq-set! tel 'guido 4127
hashq-remove! tel 'sape

hashq-ref tel 'jack ; 4098






Hash tables in Guile use explicit functions rather than syntax. It's more verbose, but Scheme compensates with association lists for small mappings:




define tel
' : (jack . 4098)
(sape . 4139)

assoc 'jack tel ; (jack . 4098)






Association lists are simple, immutable, and idiomatic for small key-value collections.






Sets



Guile doesn't have a built-in set type, but SRFI-113 provides them, or you can use sorted lists with lset- operations from SRFI-1:




use-modules : srfi srfi-1

define a '(1 2 3 4)
define b '(3 4 5 6)

lset-difference equal? a b ; (1 2)
lset-union equal? a b ; (1 2 3 4 5 6)
lset-intersection equal? a b ; (3 4)









List Comprehensions



Python:




[x**2 for x in range(10) if x % 2 == 0]






Wisp:




use-modules : srfi srfi-42

list-ec : : i (index 10)
if : = 0 : remainder i 2
expt i 2
; => (0 4 16 36 64)






SRFI-42 provides eager comprehensions. The : lines create the nested structure that Scheme expects.



Or idiomatically with map and filter:




map
lambda : x
expt x 2
filter even? : iota 10









Looping Techniques



Python:




for i, v in enumerate(["tic", "tac", "toe"]):
print(i, v)






Wisp:




let loop : : i 0
words '("tic" "tac" "toe")
when : not : null? words
format #t "~a ~a\n" i : car words
loop {i + 1} : cdr words






Or using SRFI-42:




do-ec : : i (index 3)
format #t "~a ~a\n" i
list-ref '("tic" "tac" "toe") i












6. Modules






Importing



Python:




import math
from os.path import join
import json as j






Wisp:




use-modules : ice-9 regex

use-modules
: srfi srfi-1
#:select : iota fold

use-modules
: ice-9 popen
#:prefix popen-






Guile's module system uses use-modules. The #:select option imports specific symbols, and #:prefix namespaces them — similar to Python's from X import Y and import X as Y.






Defining Modules



Python:




# mymodule.py
def greet(name):
return f"Hello, {name}!"






Wisp:




define-module : myproject mymodule
. #:export : greet

define : greet name
format #f "Hello, ~a!" name






The #:export clause explicitly lists what the module makes public — like Python's __all__ but mandatory and standard.






The Script Entry Point



Python:




if __name__ == "__main__":
main()






Wisp scripts use a shell header that invokes Guile with the right flags:




#!/usr/bin/env bash
exec guile -L . -x .w --language=wisp -e main -s "$0" "$@"
!#

define : main args
display "Hello from the command line!\n"






The -e main flag tells Guile to call the main function with command-line arguments.









7. Input and Output






String Formatting



Python:




name = "World"
f"Hello, {name}!"
"{:.2f}".format(3.14159)






Wisp:




define name "World"
format #f "Hello, ~a!" name ; "Hello, World!"
format #f "~,2f" 3.14159 ; "3.14"






Guile's format uses tilde-based directives: ~a for display, ~s for write (with quotes), ~d for integer, ~f for float, ~% for newline. It's closer to Common Lisp's format than to Python's f-strings.






File I/O



Python:




with open("data.txt", encoding="utf-8") as f:
content = f.read()

with open("output.txt", "w") as f:
f.write("Hello\n")






Wisp:




use-modules : ice-9 textual-ports

; Read entire file
define content
call-with-input-file "data.txt" get-string-all

; Write to file
call-with-output-file "output.txt"
lambda : port
display "Hello\n" port






Or using with-input-from-file for a more Python-with-like pattern:




with-input-from-file "data.txt"
lambda ()
let loop : : line (read-line)
when : not : eof-object? line
display line
newline
loop : read-line






Scheme's port system is lower-level than Python's file objects but equally capable. Every I/O function accepts an optional port argument — display "hello" port writes to a specific destination.






JSON



Guile has a JSON module:




use-modules : json

define data
json-string->scm "{\"name\": \"Ada\"}"
; => (("name" . "Ada"))

scm->json-string '((name . "Ada"))
; => "{\"name\":\"Ada\"}"












8. Errors and Exceptions






Try / Catch



Python:




try:
x = int(input("Number: "))
except ValueError as e:
print(f"Invalid: {e}")
finally:
print("Done")






Wisp:




catch #t
lambda ()
; try body
define x
string->number : read-line
when : not x
error "Invalid number"
lambda : key . args
; catch handler
format #t "Error: ~a ~a\n" key args

display "Done\n"






Guile uses catch and throw (or the newer with-exception-handler / raise-exception). The handler is a lambda that receives the error key and arguments.



The more modern style:




use-modules : ice-9 exceptions

with-exception-handler
lambda : exn
format #t "Error: ~a\n" : exception-message exn
lambda ()
string->number "not-a-number"
. #:unwind? #t









Raising Exceptions



Python:




raise ValueError("something went wrong")






Wisp:




error "something went wrong"






Or with structured keys:




throw 'value-error "something went wrong"









Custom Error Types



Python creates exception classes. Guile uses symbol keys:




throw 'insufficient-funds "Need more money"
. balance amount






Or with the newer condition system from R7RS:




use-modules : ice-9 exceptions

define-exception-type &insufficient-funds &error
make-insufficient-funds
insufficient-funds?
: balance insufficient-funds-balance
amount insufficient-funds-amount






More ceremony than Python's class hierarchy, but also more structured — each field is explicitly named and accessible.









9. Classes and Objects



This is where the languages diverge most sharply.






Python's Object-Oriented Approach






class Dog:
kind = "canine"

def __init__(self, name):
self.name = name

def speak(self):
return f"{self.name} says woof!"

rex = Dog("Rex")
rex.speak()









Wisp's Approach: GOOPS



Guile has GOOPS (GNU Object-Oriented Programming System), a powerful CLOS-style object system:




use-modules : oop goops

define-class <dog> ()
kind
. #:init-value "canine"
. #:getter dog-kind
name
. #:init-keyword #:name
. #:getter dog-name

define-method : speak (dog <dog>)
format #f "~a says woof!" : dog-name dog

define rex : make <dog> #:name "Rex"
speak rex ; "Rex says woof!"






GOOPS supports multiple inheritance, multiple dispatch (methods dispatch on all argument types, not just the first), metaclasses, and method combinations. It's more powerful than Python's object system, but also more verbose.






Inheritance



Python:




class Puppy(Dog):
def speak(self):
return f"{self.name} says yip!"






Wisp:




define-class <puppy> (<dog>)

define-method : speak (dog <puppy>)
format #f "~a says yip!" : dog-name dog









The Alternative: Just Use Data



Many Scheme programmers avoid GOOPS entirely and use plain data structures with functions — similar to Clojure's philosophy:




define : make-dog name
' : (kind . "canine")
(name . ,name)

define : dog-speak dog
format #f "~a says woof!" : assoc-ref dog 'name

define rex : make-dog "Rex"
dog-speak rex






This is simpler and often sufficient.









10. The Standard Library






Python's Batteries vs. Guile's Foundations



Python ships with modules for everything. Guile ships with fewer but more fundamental tools:




























































Python Module Guile Equivalent
os POSIX bindings (built-in)
sys (ice-9 command-line)
re (ice-9 regex)
math Built-in exact arithmetic + (ice-9 math)
json (json)
threading
(ice-9 threads) — real OS threads, no GIL!
unittest SRFI-64
datetime SRFI-19
argparse (ice-9 getopt-long)
collections SRFIs (1, 69, 113, etc.)
http
(web client), (web server)
sqlite3 Guile-DBI





Regex






use-modules : ice-9 regex

define m : string-match "[0-9]+" "hello 42 world"
match:substring m ; "42"









Threading — No GIL



This is Guile's secret weapon. Where Python has the GIL limiting true parallelism, Guile has real POSIX threads:




use-modules : ice-9 threads

call-with-new-thread
lambda ()
display "Hello from another thread!\n"

par-map
lambda : x
* x x
iota 10
; => (0 1 4 9 16 25 36 49 64 81)






par-map is parallel map — it distributes work across OS threads. No multiprocessing workaround, no async/await complexity. Just threads.






Web Server in 10 Lines






use-modules : web server

run-server
lambda : request request-body
values
' : (content-type . (text/plain))
. "Hello, World!"






Guile ships with a built-in HTTP server and client. No framework needed for basic use.









11. Advanced Standard Library






Output Formatting






use-modules : ice-9 pretty-print

pretty-print
' : (name . "Ada")
(languages . ("Python" "Wisp" "Scheme"))









Multi-threading (Continued)






use-modules : ice-9 threads

define mutex : make-mutex
define counter 0

define : increment
lock-mutex mutex
set! counter {counter + 1}
unlock-mutex mutex

; Spawn 100 threads
let loop : : i 100
when : > i 0
call-with-new-thread increment
loop {i - 1}









Exact Decimal Arithmetic



Python needs the decimal module. Scheme has exact rationals built-in:




+ 1/10 2/10               ; 3/10 (exact!)
= (+ 1/10 2/10) 3/10 ; #t
* 7/10 105/100 ; 147/200 (exact!)






No Decimal class, no imports. Exact fractions are a primitive type.









12. Virtual Environments and Packages



Python has venv and pip. Guile has a different model.



Installation:




# Guile is often pre-installed on GNU/Linux
sudo apt install guile-3.0

# Wisp
sudo apt install guile-wisp
# or from source






Dependencies:

Guile uses a load-path model rather than per-project virtual environments:




export GUILE_LOAD_PATH="/path/to/library:$GUILE_LOAD_PATH"
guile --language=wisp -s myapp.w






For project-specific dependencies, the community uses GNU Guix (a functional package manager) or manual load-path management. It's less ergonomic than pip install, but aligns with the GNU ecosystem's philosophy.



There's no PyPI equivalent. Libraries are distributed through GNU Guix, OS packages, or directly as source. This is Wisp's weakest point compared to Python.









13. Floating-Point Arithmetic



Python:




>>> 0.1 + 0.2 == 0.3
False






Wisp:




= {0.1 + 0.2} 0.3             ; #f (same problem with floats!)






Same IEEE 754, same surprises. But Scheme has an escape hatch Python doesn't — exact rationals are a first-class type, not a library:




= {1/10 + 2/10} 3/10          ; #t (exact!)
exact->inexact 1/3 ; 0.3333333333333333
inexact->exact 0.1 ; 3602879701896397/36028797018963968






That last line reveals the actual value stored for 0.1 — a ratio of two large integers. Scheme lets you move freely between exact and inexact worlds.









14. Interactive Editing



Python's REPL supports readline history and tab completion.



Guile's REPL offers similar features plus meta-commands:




,help              ; show all REPL commands
,describe display ; show documentation
,time (fib 30) ; benchmark an expression
,profile (fib 30) ; profile an expression
,L wisp ; switch to Wisp syntax
,L scheme ; switch back to Scheme






You can switch between Wisp and Scheme syntax in the same session. This is useful for learning — write in Wisp, see what Scheme it corresponds to.









15. The Secret Weapon: Macros



Like all Lisps, Wisp supports macros — compile-time code transformations. But because Wisp code looks like indented pseudocode, Wisp macros are unusually readable for Lisp macros.






Example: A Python-style for-in loop






define-syntax-rule : for-in var lst body ...
for-each
lambda : var
body ...
lst

; Now use it:
for-in word '("cat" "window" "defenestrate")
display word
newline






You just added a for-in construct to the language. It's not a function that takes a callback — it's real syntax that the compiler expands before execution.






Example: Unless






define-syntax-rule : unless condition body ...
when : not condition
body ...

unless : = 1 2
display "Math still works\n"









Example: Time-it






define-syntax-rule : time-it body ...
let : : start (current-time)
body ...
format #t "Elapsed: ~a seconds\n"
- (current-time) start

time-it
let loop : : i 1000000
when : > i 0
loop {i - 1}









Why This Matters



In Python, if you need a new control structure, you write a function with callbacks or a context manager — a workaround. In Wisp, you write a macro that generates the exact code you want, with zero runtime overhead. The result is indistinguishable from a built-in language feature.



This is the deep reason Lisp syntax exists: when code and data have the same structure, programs that write programs become natural.









The Big Picture









































































Dimension Python Wisp
Syntax Indentation + keywords Indentation + prefix notation
Paradigm Multi-paradigm (imperative-first) Multi-paradigm (functional-first)
Type System Dynamic Dynamic
Mutability Mutable by default Immutable by convention
Tail Calls No optimization (recursion limit) Guaranteed optimization
Arithmetic Floats by default Exact rationals by default
Threading GIL limits parallelism Real OS threads
Macros No Hygienic macros
OOP Classes + inheritance GOOPS (multiple dispatch) or plain data
Ecosystem Massive (PyPI) Small (Guile + GNU Guix)
Runtime CPython GNU Guile (JIT-compiled Scheme)
Best For Scripts, ML/AI, web, teaching Systems, DSLs, concurrency, extensible programs








Closing Thoughts



Wisp is not trying to replace Python. It's trying to answer a question: can Lisp be approachable?



The answer is yes. Wisp code reads like indented pseudocode. You can show it to someone who has never programmed and they'll follow the structure. But underneath that gentle surface lies one of the most powerful programming models ever devised — one where functions are data, data is code, and the language reshapes itself to fit your problem.



The ecosystem gap is real. You won't find a Wisp equivalent of NumPy or Django. But for systems programming, scripting, language design, concurrent servers, or any domain where you want to think differently about code — Wisp offers something Python cannot: a Lisp you can read at a glance.




display "Welcome to Wisp.\n"
display "Where indentation meets imagination.\n"






Get started: install Guile, install Wisp, and type ,L wisp in the Guile REPL. The parentheses are gone. The power remains.






This article was written as a companion to the official Python tutorial. Every section maps to a chapter in that tutorial, showing the same concepts through Wisp's indentation-sensitive Lisp lens. For more on Wisp, visit draketo.de/software/wisp.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Python to Wisp: The Lisp That Stole Python's Indentation

Thematisch verwandte Begriffe: Python, Wisp, Lisp, That · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-59815 | Joplin is an open source note-taking and to-do application that organise…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick