Upgrade to Pro — share decks privately, control downloads, hide ads and more …

What Python Can Learn From Other Languages

What Python Can Learn From Other Languages

Presented at North Bay Python 2024 on 2024-06-30.

Noah Kantrowitz

June 30, 2024
Tweet

More Decks by Noah Kantrowitz

Other Decks in Programming

Transcript

  1. WHAT PYTHON CAN LEARN FROM OTHER LANGUAGES Noah Kantrowitz -

    coderanger.net 1 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  2. NOAH KANTROWITZ • He/him • coderanger.net | cloudisland.nz/@coderanger • Kubernetes

    and Python • SRE/Platform for Geomagical Labs, part of IKEA • We do CV/AR for the home 2 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  3. PYTHON PYTHON IDEAS But not the mailing list 4 North

    Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  4. PHP DEPLOYMENT • Drag and drop • foo.php → http://example.com/foo.php

    • Deep editor integration 6 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  5. AUTOLOADERS • new \Foo\Bar(1, 2, 3) • Foo\Bar.php • namespace

    Foo; class Bar { } • No require required "autoload": { "psr-4": {"Foo\\": "src/"} } 7 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  6. STANDARD LIBRARY • Batteries Included ... for a speci!c niche

    • Database libraries • Libcurl • PECL as a secondary stdlib 8 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  7. TEMPLATING Hello <?php echo $world ?> <div> <?php if($val) {

    ?> <p>and some more HTML<"p> <?php } ?> <"div> 9 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  8. SYMBOLS • :foo ('foo in LISP #foo in Smalltalk) •

    sys.intern("foo") • Strings with bene!ts • myfn(foo=1), maybe MyStrEnum.FOO 11 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  9. BLOCKS foo do |x| x + 1 end def _inner(x):

    return x + 1 foo(_inner) 12 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  10. METHOD CHAINING y = x.one do |val| .." end.two do

    |val| .." end def _one(val): ..# def _two(val): ..# y = x.one(_one).two(_two) 13 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  11. TANGENT: DART METHOD CASCADING a.b()."c() ."d(); x = a.b() x.c()

    x.d() 14 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  12. BUILDERS x = Foo.new do |cfg| cfg.bar = 1 if

    other cfg.baz(2, 3) end do # What if? x = with Foo as cfg: cfg.bar = 1 if other: cfg.baz(2, 3) 15 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  13. RUBY FOR GOOD • Court Appointed Special Advocates • National

    Diaper Bank Network • Chicago Tool Library • Habitat For Humanity 16 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  14. TYPESCRIPT (AND JAVASCRIPT) 17 North Bay Python 2024 – Noah

    Kantrowitz – @coderanger@cloudisland.nz
  15. NULL COALESCING SAFE NAVIGATION x ?" y x?#foo?#bar() y if

    x is None else x x.foo.bar() if x is not None and x.foo is not None else None 18 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  16. OBJECTS AND INLINE TYPES function foo(x: {bar: string}) { baz(x.bar);

    } # What if? def foo(x: TypedDict["bar": str]): baz(x["bar"]) 19 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  17. PROMISES (AND FUTURES) fetch(`/search`) .then(resp =" resp.json()) .then(data =" fetch(`/detail/${data.id}`))

    .then(resp =" resp.json()) .then(data =" console.log(data.name)); async def foo(): resp = await fetch("/search") data = await resp.json() resp = await fetch(f"/detail/{data['id']}") 20 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  18. GOROUTINES AND CHANNELS messages :" make(chan string) go func() {

    messages #- "ping" }() msg :" #-messages # Soon? messages = Channel[str]() def func(): messages.append("ping") subinterpreter.run(func) msg = messages.pop() 22 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  19. INTERFACE CASTS type Foo interface { Bar(int) int } y,

    ok = x.(Foo) y.Bar(1) @typing.runtime_checkable class Foo(typing.Protocol): def bar(self, x: int) -# int: ..% class Impl: def bar(self, x: str) -# str: ..% x = Impl() isinstance(x, Foo) =' True x.bar(1) # Oops wrong type 23 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  20. STATIC COMPILATION • GOOS=windows GOARCH=amd64 go build • FROM scratch

    • ./myapp • xkcd://1987 24 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  21. PERL PIE perl -pi -e 's/VAR/Hello/g' input.txt What if? python

    -m pie 're.sub("VAR", "Hello")' input.txt 26 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  22. C# AND LINQ int[] scores = [97, 92, 81, 60];

    IEnumerable<int> scoreQuery = from score in scores where score > 80 select score; • Dataframes • DuckDB 27 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  23. SCHEME AND CONTINUATIONS (call/cc (lambda (c) (c 42))) =" 42

    (call/cc (lambda (c) (+ 1 (c 42)))) =" 42 def call_cc(f): ex = type('Continuation', (Exception,), {}) def c(val): raise ex(val) try: return f(c) except ex as exc: return exc.args[0] def foo(c): c(42) call_cc(foo) =# 42 28 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  24. SEASIDE changeBackgroundColor |color| color :" self call: ColorPicker new. "

    ^ Respond to client and then wait for another request" blog backgroundColor: color 29 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  25. TANGENT: SMALLTALK & FLOW CONTROL class True: def if_true(self, f):

    return f() def if_false(self, f): pass class False: def if_true(self, f): pass def if_false(self, f): return f() def _inner(): print("Yes") x.if_true(_inner) value = 0 def _other(): x = value <# 10 def _inner(): value += 1 x.if_true(_inner) return x y = True() y.do_while(_other) 30 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  26. EVEN MORE TANGENT: FORTH \ quit is the top level

    preForth interpreter loop. It reads tokens \ and handles them until an error occurs or the input is exhausted. : quit ( -" ) token \ get next token \ run interpreters ?: \ :-definition ?code \ code definitions ?pre \ pre* ?\ \ comment dup ?exit drop \ unhandled or EOF tail quit ; \ cycle 31 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  27. ERLANG AND OTP SUPERVISORS • Task exception was never retrieved

    – Oops! init(_Args) -" SupFlags = #%strategy =' one_for_one, intensity =' 1, period =' 5}, ChildSpecs = [#%id =' myapp, start =' {myapp, start_myapp, []}, restart =' permanent, shutdown =' brutal_kill, type =' worker, modules =' [myapp]}], {ok, {SupFlags, ChildSpecs}}. 32 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  28. SOME DAY: PY OTP? async with loop.sup() as s1: c

    = s1.create_task(cache_manager()) async with s1.sup(on_error=emit_log) as s2: s2.create_task(web_server(c)) async with loop.sup(watchdog=5) as s3: s3.create_task(cleanup()) 33 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  29. WHERE DO WE GO FROM HERE 34 North Bay Python

    2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  30. MACROS! macro_rules! add_as{ ($a:expr, $b:expr, $typ:ty) =" { $a as

    $typ + $b as $typ } } (defmacro setq2 (v1 v2 e) (list 'progn (list 'setq v1 e) (list 'setq v2 e))) 35 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  31. ABSTRACT SYNTAX TREES expr = BoolOp(boolop op, expr* values) |

    NamedExpr(expr target, expr value) | BinOp(expr left, operator op, expr right) | UnaryOp(unaryop op, expr operand) | Lambda(arguments args, expr body) | IfExp(expr test, expr body, expr orelse) | Dict(expr* keys, expr* values) ..# 37 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  32. S-EXPRESSIONS • An atom • a • A pair of

    s-expressions • (a . b) (* 1 (+ 2 3)) _______ / ___\___ * / __\__ 1 / _\_ + / \ 2 3 38 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  33. LISP • (defmacro addone (x) (list '+ '1 x)) •

    Oh look, atom 'defmacro, record this into the list of macros • (* 1 (addone (- 2 1))) • Oh look, atom 'addone is a macro, do the macro thing! • Execute (list '+ '1 x) • Got back ('+ '1 ('- '2 '1)) • (* 1 (+ 1 (- 2 1))) 39 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  34. METAPROGRAMMING • Tokenize → Parse → Compile → Execute •

    Instead: Parse → Macro Compile → Macro Execute → Parse 40 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  35. RUST • Procedural macros • Custom #[derive] • Attribute-like #[proc_macro_attribute]

    • Function-like #[proc_macro] • pub fn foo(input: TokenStream) -> TokenStream { • Declarative macros – macro_rules! 41 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  36. MACRO_RULES! macro_rules! vec { ( $( $x:expr ),* ) ="

    { { let mut v = Vec:$new(); $( v.push($x); )* v } }; } let myvec: Vec<u32> = vec![1, 2, 3]; /" Becomes ..$ let myvec: Vec<u32> = { let mut v = Vec:&new(); v.push(1); v.push(2); v.push(3); v }; 42 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  37. WHAT TO TAKE FROM ALL THIS? 43 North Bay Python

    2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  38. THANK YOU Find Me Later For Questions 44 North Bay

    Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz
  39. PHP Ease of deployment Auto load and its deep integration

    with Composer Expansive std lib Ruby Easy lambdas via blocks Flow programming Symbol literals Builder pattern Go Static compilation and FROM scratch Interfaces 45 North Bay Python 2024 – Noah Kantrowitz – @coderanger@cloudisland.nz