shirok / Gauche

Scheme Scripting Engine
https://practical-scheme.net/gauche
Other
815 stars 81 forks source link

Add (define (const v) (lambda _ v)) to the core library #729

Closed volodymyrprokopyuk closed 4 years ago

volodymyrprokopyuk commented 4 years ago

Hello,

In Gauche I'm missing the const higher-order function that is present in other Scheme implementations (Guile). What is the idiomatic Gauche code or equivalent Gauche procedure that implements the const-like functionality?

Example use case.

;; Should be part of Gauche's core library
(define (const v)
  "Returns a procedure that accepts any number of arguments and always returns the value v"
  (lambda _ v))

(let ([ht (hash-table eq-comparator '(a . 1) '(b . 2))])
  ;; Workaround that implements const with cut and identity
  #?=(hash-table-ref ht 'b (cut identity #f) identity)
  ;; More readable, consice, and idiomatic equivalent
  #?=(hash-table-ref ht 'b (const #f) identity))
shirok commented 4 years ago

If it's Gauche-specific code, you can write (^_ v). It's shorter.

I've been tempted to add const or constantly as you suggest, but so far refrained from it since invoking a closure with variable-length arguments has a tiny bit of overhead. If you know the number of arguments to be passed, give the number of arguments explicitly is betetr (it also tells the reader that how the constant closure is called).

If there's more requests, I might add it. I like constantly per Common Lisp.

pclouds commented 4 years ago

It's not exactly a request, but the limitations of const could be documented so people can choose to use or not to use it. Is there any downside from adding it otherwise?

shirok commented 4 years ago

If the user knows the performance implication, it's ok. (I might be able to add some optimization so that the caller can know the arguments are ignored.)

Question - how many implementations are using const? It is short but too generic, so I'm inclined to constantly but if there are more than a few implementations using const I'm fine to follow.

lassik commented 4 years ago

@johnwcowan Didn't you propose a procedure like constantly in a SRFI or pre-SRFI recently? I forget which one.

johnwcowan commented 4 years ago

It's on my Combinators page.

pclouds commented 4 years ago

Question - how many implementations are using const?

I scanned through a few implementations I have...

Chicken uses constantly

Larceny has constantly (but in MzScheme/misc.sch, I suppose it's just imported from there). It could be internal though, I tried the repl and constantly is not recognized there.

It doesn't look like Chibi, Cyclone, Sagittarius, Gambit and Gerbil has one either (there's const-value in the benchmark suite, but I don't think that counts; same for "const" in one of the tests of Sagittarius)

Some implementations define (internally?) const? to (I guess) check if an object is of constant type. That's a minus for const.

shirok commented 4 years ago

So, constantly is a bit more popular?

pclouds commented 4 years ago

Looks like so. There are still a few big schemes out there, but I don't intend to grab more than what I already have just to search this.

lassik commented 4 years ago

From the Docker containers, these have neither const nor constantly:

shirok commented 4 years ago

Ok, added.

volodymyrprokopyuk commented 4 years ago

Hello! Sorry for the late response. It is a real pleasure to see you to care so much about Gauche performance! I'm really impressed with the quality of Gauche implementation and libraries! Thank you very much for the high quality product Gauche!

I'm perfectly fine with constantly and for sure I'm taking note on the Gauche-specific very concise and handy shortcut ^ _ v.