Re: @Memoize doesn't work in Python 3 ? -- (Gauche scheme?)

Liste des GroupesRevenir à cl misc 
Sujet : Re: @Memoize doesn't work in Python 3 ? -- (Gauche scheme?)
De : 643-408-1753 (at) *nospam* kylheku.com (Kaz Kylheku)
Groupes : comp.lang.python comp.lang.lisp comp.lang.misc
Date : 30. Jul 2024, 00:05:15
Autres entêtes
Organisation : A noiseless patient Spider
Message-ID : <20240729153816.517@kylheku.com>
References : 1
User-Agent : slrn/pre1.0.4-9 (Linux)
On 2024-07-29, HenHanna <HenHanna@devnull.tb> wrote:
>
@Memoize   doesn't  work  in Python 3  ?
>
Do we have this in  Gauche scheme?  (Common Lisp?)

In TXR Lisp there is something called parameter list macros,
or parameter macros, for short.

It is my invention.

Parameter list macros are named after keyword symbols.

When a keyword symbol occurs at the head of a macro or lambda
parameter list, if that symbol has a parameter macro binding,
the expander is invoked. The expander takes four arguments:
the parameter list, the body, a macro environmet and the entire
form that is defining the function (for error reporting).

The expander must produce a transformed parameter list, and
transformed function body.

No memoizing parameter macro is included in the language,
but the manual gives an example of how to write one. Excerpt:

    The following example shows the implementation  of  a  parameter
    macro  :memo  which provides rudimentary memoization.  Using the
    macro is extremely easy. It is a matter of simply inserting  the
    :memo  keyword at the front of a function's parameter list.  The
    function is then memoized.

      (defvarl %memo% (hash :weak-keys))                             
      (defun ensure-memo (sym)
(or (gethash %memo% sym)
    (sethash %memo% sym (hash))))

      (define-param-expander :memo (param body)
(let* ((memo-parm [param 0..(posq : param)])
       (hash (gensym))                                                                 (key (gensym)))
  ^(,param (let  ((,hash (ensure-memo ',hash))
  (,key (list ,*memo-parm)))
     (or (gethash ,hash ,key)
(sethash ,hash ,key (progn ,*body)))))))

    The above :memo macro may be used to define a memoized Fibonacci
    function as follows:

      (defun fib (:memo n)
(if (< n 2)
  (clamp 0 1 n)
  (+ (fib (pred n)) (fib (ppred n)))))

    All that is required is the insertion of the :memo keyword.

Not shown in the example is that :memo only memoizes over the
required parameters (ones before the colon : symbol that separates
fixed from optional).  :memo does nothing with the parameters; they
are returned as is.

TXR Lisp does not have keywords in the native function calling model, but
provides a :key parameter macro that implements them via code transformation.
This uses -- to separate the specification of key parameters:

  (lambda (:key a b c -- foo bar (xyzzy 42))
    ...)

There is no strict checking (i.e. what you opt out of in Common Lisp
by means of &allow-other-keys).

The entire implementation is here:

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


An interesting observation is that TXR Lisp also has a defset
macro (similar to Common Lisp defsetf).

When you use defset to define a place with keywords, it
Just Works, even though defset knows nothing about :key at all.

Like in the test cases related to (defset :foo ...)
in this file:

https://www.kylheku.com/cgit/txr/tree/tests/012/defset.tl

I was blown away, not expecting that to work.

Given

  (defset foo (:key x y -- a b c (d 4)) n ^(bar ,x ,y, a, b, c ,d ,n))

With the defset macro having no knowledge of the existence of :key,
this works:

  (inc (foo 1 2 :a 3 :b 4) 5)   ;; increment (foo ...) place by 5

producing an expansion like:

  (let ((#:new-value (+ (foo 1 2 :a 3 :b 4) 5)))
    (bar 1 2 3 4 () 4 #:new-value)))

The :a and :b key values are decoded and inserted in the right spot in the (bar
form), and this happens when the place defined by defset is expanded by a
place-mutating form like inc.

More complex example showing that the arguments are evaluated just
once by the increment operation:

  2> (expand '(inc (foo (one) (two) :a (three) :b (four)) 5))
  (let ((#:g0074 (one))
(#:g0075 (two))
(#:g0076 (three))
(#:g0077 (four)))
    (let ((#:g0026 (+ (foo #:g0074
       #:g0075 :a
       #:g0076 :b
       #:g0077)
      5)))
      (bar #:g0074
       #:g0075 #:g0076
       #:g0077 ()
       4 #:g0026)))

Common Lisp implementations of defsetf typically fudge around with keyword
argument parsing in order to make stuff like this work.

--
TXR Programming Language: http://nongnu.org/txr
Cygnal: Cygwin Native Application Library: http://kylheku.com/cygnal
Mastodon: @Kazinator@mstdn.ca

Date Sujet#  Auteur
29 Jul 24 * @Memoize doesn't work in Python 3 ? -- (Gauche scheme?)2HenHanna
30 Jul 24 `- Re: @Memoize doesn't work in Python 3 ? -- (Gauche scheme?)1Kaz Kylheku

Haut de la page

Les messages affichés proviennent d'usenet.

NewsPortal