GithubHelp home page GithubHelp logo

technologicat / spicy Goto Github PK

View Code? Open in Web Editor NEW
6.0 3.0 0.0 16 KB

Automatic currying for Racket

License: GNU Lesser General Public License v3.0

Racket 100.00%
currying racket racket-lang curry example

spicy's Introduction

spicy: Automatic currying for Racket

#lang spicy

(define (map f)
  (foldr (compose cons f) empty))

(module+ main
  (define a '(1 2 3))
  (define (f x) (* x x))
  (map f a))

Compare not spicy:

#lang racket

(define (->1 f) (λ (a b) (values (f a) b)))
(define (map f . args)
  (apply curry foldr (compose cons (->1 f)) empty args))

(module+ main
  (define a '(1 2 3))
  (define (f x) (* x x))
  (map f a))

For fewer parentheses, combine spicy with sweet-exp:

#lang sweet-exp spicy

define map(f)
  foldr (compose cons f) empty

module+ main
  define a '(1 2 3)
  define (f x) (* x x)
  map f a

To spice locally, spicy/sauce:

#lang sweet-exp racket

require spicy/sauce

module+ main
  with-curry
    define mymap-local(f)
      foldr (compose cons f) empty
    mymap-local
      λ (x) {x * x}
      '(1 2 3)
  ;
  splicing-with-curry
    define mymap(f)
      foldr (compose cons f) empty
  ;; now autocurry is off
  (mymap (λ (x) {x * x}))
    '(1 2 3)

Examples

Some more simple examples, based on those in Hughes (1984): Why functional programming matters and racketified.

For details, take the tour.

Human-readable rules

  • All function applications are curried. Currying is applied from the left.
  • Keyword arguments can be passed in the initial call, just like when currying manually in Racket.
  • Any arguments over max-arity are passed through on the right, by constructing a multiple-values object.
    • This makes the above example possible, although the arities of f and cons are different.
  • If the application also returns a multiple-values, the remaining arguments (if any) are appended into it.
  • If the application produces only one value, which is another curried procedure, it is applied to the remaining arguments.
    • See the tour for where this is useful.
  • The auto-curried procedure immediately switches to the mode where any acceptable arity triggers a call.
    • In contrast, currying manually in Racket always curries at least once (if a higher arity exists).
    • Hence some variadic functions (notably e.g. +, *) cannot be auto-curried in spicy, since they accept any arity ≥ 0.
    • Curry manually to revert to Racket's usual processing: + 1 → 1, but curry + 1#<procedure:curried>.
      • It will still use the customized curry function from spicy, but skips the automatic mode switching.

Installation

  • Copy the files anywhere you want.
  • Open a terminal in the spicy/ subfolder.
  • raco pkg install

To uninstall, raco pkg remove spicy.

How it works

Essentially, a custom #%app macro to rewrite function applications at compile time, a customized curry, and four lines of code to package that as a language that borrows everything else from Racket.

Also, the compose function is overridden by a curry-aware version, which spices its arguments.

Disclaimer

Primarily meant for teaching purposes. Tested only on toy examples.

Not completely seamless, and cannot be. Automatic currying and variadic functions do not play well together; also, dynamic typing implies that the system won't notice if you miss an argument somewhere - which may make your code hard to debug. For discussion on the topic, see e.g. here, here and here.

License

GNU LGPL 3.0.

Contains a customized version of Racket's curry, which is used under GNU LGPL 3.0.

Dependencies

spicy's People

Contributors

technologicat avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

spicy's Issues

Upgrade curry to Racket 7

This package was created on Racket 6.x. The updated curry in Racket 7.x can pass keyword arguments at any time; not only in the initial call as the one from Racket 6.x.

Upgrading requires some thought, because spicy is essentially a customized curry.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.