[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: Keyword args
From: |
Andy Wingo |
Subject: |
Re: Keyword args |
Date: |
Mon, 13 Dec 2010 21:00:47 +0100 |
User-agent: |
Gnus/5.13 (Gnus v5.13) Emacs/23.2 (gnu/linux) |
On Mon 13 Dec 2010 03:10, Daniel Colascione <address@hidden> writes:
> Clearly, the solution is more uniform keyword argument parsing; either
> library functions in C could be provided, or make-network-process could
> be made a Lisp keyword-parsing front-end for some horrible
> %make-network-process that implements the functionality.
FWIW, Guile supports keyword arguments natively. IMO the proper way to
do things is to keep a uniform calling convention, and allow procedures
to parse arguments themselves, with low-level support.
scheme@(guile-user)> (lambda* (#:key (foo 42)) foo)
$1 = #<procedure 1c2f080 at standard input:1:0 (#:key foo)>
scheme@(guile-user)> ,disassemble $1
Disassembly of #<procedure 1c2f080 at standard input:1:0 (#:key foo)>:
Here we have some instructions that aren't disassembled quite as
perspicaciously as one might like, but they take the args on the stack,
and shuffle the non-positional args up:
0 (assert-nargs-ge 0 0)
3 (bind-optionals/shuffle 0 0 0 0 0 1)
And here we bind keywords. This says "fetch the keywords from the
constant table at index 1, and scan the non-positional args for one
keyword, disallowing other keywords.
10 (bind-kwargs 0 1 0 1 0)
It's somewhat complicated code, but it's a const only borne by keyword
arguments. Here we have the code that initializes `foo' if it's not
given:
16 (reserve-locals 0 1)
19 (local-bound? 0)
21 (br-if :L111) ;; -> 29
25 (make-int8 42) ;; 42
27 (local-set 0) ;; `foo'
And finally (!) the main body:
29 (local-ref 0) ;; `foo'
31 (return)
Some tests:
> (define (fib n) (if (< n 2) 1 (+ (fib (- n 1)) (fib (- n 2)))))
> ,time (fib 35)
$1 = 14930352
clock utime stime cutime cstime gctime
2.99 2.99 0.01 0.00 0.00 0.00
> (define* (fibk #:key (n 0)) (if (< n 2) 1 (+ (fibk #:n (- n 1)) (fibk #:n
(- n 2)))))
> ,time (fibk 35)
<stdin>:5:6: warning: possibly wrong number of arguments to `fibk'
While executing meta-command:
ERROR: Odd length of keyword argument list
> ,time (fibk #:n 35)
$2 = 14930352
clock utime stime cutime cstime gctime
5.01 4.99 0.00 0.00 0.00 0.00
FWIW on this machine a byte-compiled elisp (fib 35) on emacs takes about
6 seconds.
I wrote more about this sort of thing here:
http://wingolog.org/archives/2009/11/07/case-lambda-in-guile
http://wingolog.org/archives/2009/11/08/optionals-keywords-oh-my
Our elisp support uses this native infrastructure for keywords and
optionals, but there obviously are some differences regarding
implementation of dynamic scope. Lexical binding is a lot cheaper, for
Guile, but we hope to get dynamic binding cheap too.
Anyway, I would like to discourage complicated implementations in
"user-space" for keyword arguments. They should be a core language
feature, for all the reasons I gave in my first article.
Happy hacking,
Andy
--
http://wingolog.org/
- Re: Return, (continued)
- Re: Return, tomas, 2010/12/07
- Re: Return, MON KEY, 2010/12/06
- Re: Return, Stephen J. Turnbull, 2010/12/07
- Re: Return, David Kastrup, 2010/12/07
- Re: Return, Stephen J. Turnbull, 2010/12/07
- Re: Return, Richard Stallman, 2010/12/08
- Re: Return, Daniel Colascione, 2010/12/10
- Keyword args (was: Return), Helmut Eller, 2010/12/10
- Re: Keyword args, Daniel Colascione, 2010/12/12
- Re: Keyword args, Helmut Eller, 2010/12/13
- Re: Keyword args,
Andy Wingo <=
- Re: Keyword args, Miles Bader, 2010/12/14
- Re: Keyword args, Helmut Eller, 2010/12/14
- Re: Return, MON KEY, 2010/12/07
- Re: Return, Stephen J. Turnbull, 2010/12/08
- Re: Return, MON KEY, 2010/12/08
- Re: Return, Stephen J. Turnbull, 2010/12/09
- Re: Return, Samuel Bronson, 2010/12/07
- Re: Return, Stephen J. Turnbull, 2010/12/08
- Re: Return, Samuel Bronson, 2010/12/08