News for hackers. Stuff that matters.
Re:JEP 443: Unnamed Patterns and Variables (Preview) by kazinator on Wednesday March 22, 2023 @12:27AM (#35256831)
TXR Lisp:

  1> (time-struct-utc (time))
  #S(time year 2023 month 3 day 22 hour 4 min 25 sec 0 wday 3 yday 80 dst nil
          gmtoff 0 zone "GMT")
  2> (match @(struct @type year @y) (time-struct-utc (time))
       (list type y))
  (#<struct-type time> 2023)
We don't want to capture the type: use the @nil pattern which matches an object without capturing a variable:

  3> (match @(struct @nil year @y) (time-struct-utc (time))
     y)
  2023
Wrong/nonexistent type:

  4> (match @(struct foo year @y) (time-struct-utc (time))
       y)
  ** expr-4:1: warning: if-match: no such struct type: foo
  ** match: @(struct foo year @y) failed to match object #S(time year 2023 month 3 day 22 hour 4 min 29 sec 32 wday 3 yday 80
                                                               dst nil gmtoff 0 zone "GMT")
It's all macros, found in one file:

https://www.kylheku.com/cgit/txr/tree/stdlib/match.tl

If a student handed in a pattern matching system that didn't have a "null variable" pattern, I would not award full marks. That's just useless beyond words; you can't do things like

  (match (@a @nil @nil @c) ...)
to match a four-element list, capturing the first and last element; you have to name the variables and then tell your compiler they are deliberately not used.
Re:JEP 443: Unnamed Patterns and Variables (Preview) by kazinator on Wednesday March 22, 2023 @12:44AM (#35256929)
Under the hood:

  1> (compile-toplevel '(match @(struct @type year @y) (time-struct-utc (time))
       (list type y)))
  #<sys:vm-desc: 986dff0>
Disassembly of VM descriptor, annotated:

  2> (disassemble *1)
Constant data table (preinitialized registers D0 through D3):

  data:
      0: year
      1: t
      2: match
      3: @(struct @type year @y)
Referenced functions, indexed by number:

  syms:
      0: time-struct-utc
      1: time
      2: structp
      3: struct-type
      4: slotp
      5: slot
      6: list
      7: sys:match-pat-error
Actual code:

  code:
      0: 20000003 gcall t3 1
      1: 00000001
      2: 2001000D gcall t13 0 t3
      3: 00030000
Call (time), result in T3. Then (time-struct-utc T3) -> T13.

      4: 20010002 gcall t2 2 t13
      5: 000D0002
(structp T3) -> T2

      6: 38000017 if t2 23
      7: 00000002
If T2 is true, keep going, otherwise jump to 23

      8: 20010009 gcall t9 3 t13
      9: 000D0003
Call (struct-type T13) to get the structure's type object.

     10: 2C0B0009 movsr t11 t9
This is a failure in dataflow analysis to remove a useless register copy.

     11: 20020002 gcall t2 4 t9 d0
     12: 00090004
     13: 00000400
D0 is the year symbol; this is calling slotp to test whether the incoming struct object has a year slot.

     14: 38000017 if t2 23
     15: 00000002
If so, continue, otherwise go to error block at 23.

     16: 20020008 gcall t8 5 t13 d0
     17: 000D0005
     18: 00000400
Now get the year slot's value.

     19: 2002000C gcall t12 6 t11 t8
     20: 000B0006
     21: 00000008
List the type in T11 and the year value in T8, into a list held in T12.

     22: 1000000C end t12
Execution ends returning T12.

23 is the error block: run-time function sys:match-pat-error is called with some arguments, like D3, which holds the source code of the pattern.

     23: 20030002 gcall t2 7 d2 d3 t13
     24: 04020007
     25: 000D0403
Not reached, since that function throws:

     26: 10000002 end t2
  instruction count:
     13
  #<sys:vm-desc: 986dff0>