Skip to content

arthurmaciel/mu

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

8 Commits
 
 
 
 
 
 

Repository files navigation

mu

An extended Scheme lambda with optional and named (destructured) parameters.

It is a proof-of-concept of how Scheme implementations could extend the lambda form to parse/destructure its arguments in alternative ways, and allow faster prototyping.

It is highly inspired on the ideas discussed with Lassi Kortela and Marc Nieper-Wißkirchen on this issue and the beautiful idea of extending Scheme core syntax, maybe targeting R8RS (SRFI-201 is highly inspiring in this sense too, although not related to this implementation).

These high-level abstractions implemented in Scheme are very inneficient (almost 20x slower than actual lambda in the worst case - tested in Cyclone Scheme). Maybe if implemented in the compiler it could run much faster.

This extension is proposed mainly for experimentation and research purposes.

Supported arguments forms and examples

;;; Nothing new here ------------------------------
;; NO parameters
;; (mu () body)
> ((mu () 1)) 
1

;; Paramters list
;; (mu args body)
> ((mu x x) 1 2 3)
(1 2 3)

;; POSITIONAL parameters only
;; (mu (a) body)
> ((mu (a) 
     (list a)) 
   1)
(1)

;; POSITIONAL parameters only - with REST
;; (mu (a . rest) body)
> ((mu (a . r) 
     (list a r)) 
   1 2)
(1 (2))


;;; Start of OPTIONAL parameters ----------------------
;; POSITIONAL parameters with OPTIONAL ones
;; (mu (a (b 2)) body)
> ((mu (a (b 2)) 
     (list a b)) 
   1)
(1 2)

> ((mu (a (b 2)) 
     (list a b))
   1 3)
(1 3)

;; POSITIONAL parameters with OPTIONAL ones - with REST
;; (mu (a (b 2) . rest) body)
> ((mu (a (b 2) . r) 
     (list a b r)) 
   1 5 7)
(1 5 (7))

> ((mu (a (b 2) . r) 
     (list a b r)) 
   1)
(1 2 ())

;; OPTIONAL parameters only (they are optional, but still *positional* parameters)
;; (mu ((b 2)) body)
> ((mu ((b 2)) 
     (list b)))
(2)

> ((mu ((b 2)) 
     (list b)) 
   9)
(9)

;; OPTIONAL parameters only (they are optional, but still *positional* parameters) - with REST
;; (mu ((b 2) . rest) body)
> ((mu ((b 2) . r) 
     (list b r)))
(2 ())

> ((mu ((b 2) . r) 
     (list b r)) 
   9)
(9 ())

> ((mu ((b 2) . r) 
     (list b r)) 
   9 7)
(9 (7))


;;; NAMED parameters through single alist -------------
;; It works with proper (eg. '((a . 1) (b . 2)) and 
;; improper (eg. '((a 1) (b 2)) alists.

;; (mu (a) body)
> ((mu (a) 
     (list a)) 
   '((a 1)))
(1)

;; (mu (a . rest) body)
> ((mu (a . r) 
     (list a r)) 
   '((a 1)))
(1 ())

;; (mu (a (b 2)) body)
> ((mu (a (b 2)) 
     (list a b)) 
   '((a 1)))
(1 2)

> ((mu (a (b 2)) 
     (list a b)) 
   '((a 1) (b 3)))
(1 3)

;; (mu (a (b 2) . rest) body)
> ((mu (a (b 2) . r) 
     (list a b r)) 
   '((a 1)))
(1 2 ())

> ((mu (a (b 2) . r) 
     (list a b r)) 
   '((a 1) (b 3)))
(1 3 ())

> ((mu (a (b 2) . r) 
     (list a b r)) 
   '((a 1) (b 3) (r 5)))
(1 3 (5))

> ((mu (a (b 2) . r) 
     (list a b r)) 
   '((a 1) (r 5)))
(1 2 (5))

;; 
> ((mu (a (b 2) . r) 
     (list a b r)) 
   '((r 5) (b 3) (a 1))) ;; the order doesn't matter
(1 3 (5))

Caveats (and comments)

  • perfomance penalty: implement it in the compiler?

  • confusing syntax for optional parameters: they just add parens (and that's the virtue and curse of LISPs)

  • still can't handle passing some optional parameters, but not all of them (see here).

  • extra step to pass an alist as a parameter content:

> (define my-config-alist '((height . 10) (width . 30)))
> ((mu (a) 
     (cdr (assoc 'height a)))
   `((a ,my-config-alist)))
10

We see how we could just write procedures for parameter destructuring:

> (define get-height 
    (mu (height) 
      height)) ;; do something else with it
> (get-height my-config-alist)
10

We could see other applications for arguments destructuring with alists if we imagine use cases for hash-table->alist or STRUCTNAME->alist (in a more useful record type like Chicken's one).

Ideas (suggestions are very welcomed!)

  • Instead of/in addition to named parameters through an alist, mu could provide pattern matching as in SRFI-201 (defined in section The pattern matching (destructuring) lambda form).

  • Instead of/in addition to named parameters through an alist, mu could allow a property list of SRFI-88 keywords, like proposed in SRFI-89. Eg. (keyword1: value1 keyword2: value 2 ...). Maybe this would make the code cleaner and avoid the extra step when passing a keyword.

  • Maybe use a special keyword or reader syntax to point to the named and optionals parameters like Chicken's #!key and #!optional? Maybe wrap the named values in { }? This way we could just lift positional-only mu procedures directly into a lambda one, i.e. overhead only if parameter destructring is used.

About

An extended Scheme lambda with optional and named parameters

Resources

Stars

2 stars

Watchers

1 watching

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages