1

I'm reading (looking at) the Guile Reference Manual but I do not understand some notational conventions specified by SRFI.

Note that the Guile Reference Manual seems to follow the structure of the SRFI documents. I browsed the source code on GuixSD to find some use cases without luck.

For example, I do not understand the meaning of kons and knil.

string-fold kons knil s [start [end]]

Hyperlinks: SRFI-13 or Guile Reference Manual

Q: Where are the Scheme notational conventions presented?

2 Answers2

1

This notation for optional arguments is not only used here. It is also used in Unix program usage.

string-fold kons knil s [start [end]]

The content each bracket is optional.

Means that it may be called as:

string-fold kons knil s 
string-fold kons knil s start
string-fold kons knil s start end

kons and knil are named such to denote their relationship with cons and nil where (string-fold cons nil s) <=> (string->list s) except that it can produce other structures than lists by providing a suitable cons like function and a nil value.

Dan D.
  • 73,243
  • 15
  • 104
  • 123
  • I do not understand especially the keywords `kons` and `knil`. –  Aug 10 '19 at 16:09
  • 1
    @Fólkvangr They're not keywords, they're the names of the parameters (just like `s`, `start` and `end`). – sepp2k Aug 10 '19 at 16:18
  • @sepp2k: You are right. I know that the word "keyword" has a special meaning in Scheme but I do not speak english very well. –  Aug 10 '19 at 16:22
  • Your explanation makes sense so I suppose the reader have to guess the notations using some context or background. –  Aug 10 '19 at 16:51
  • There is no relationship between `kons` and `cons`, however the documentation makes it clear `knil` will be used as initial second argument and that it should have the same type as the result while the first argument of `kons` should take a string. eg. `0` as `knil` and `(lambda (c i) (+ (char->integer c) i))` can be used as `kons` and the result will be the sum of the ascii codes. – Sylwester Aug 13 '19 at 15:38
  • @Sylwester There is a relationship. Kons and knil denote a reduction function and a initial object in a family of which the pair (cons, nil) are well known members. The names were chosen to resemble them. They have the types (a×b->b, b). Theses form the arguments to folds. – Dan D. Aug 14 '19 at 02:11
0

There is no previous knowledge needed to read and understand the SRFI. Taken straight from the SRFI under Procedure specification:

  • Parameters given in square brackets are optional.
  • An s parameter is a string.

The other parameters, kons and knil, are not mentioned and thus they are mere names that needs explaining. string-fold gets explained twice:

The left-fold operator maps the kons procedure across the string from left to right

(... (kons s[2] (kons s[1] (kons s[0] knil))))

string-fold obeys the (tail) recursion:

(string-fold kons knil s start end) ; ==
(string-fold kons (kons s[start] knil) start+1 end)

Thus it shows that:

(string-fold add-char 0 "abracadabra" 8)

is the same as:

(string-fold add-char (add-char #\b 0) "abracadabra" 9 11)

is the same as:

(add-char #\a (add-char #\r (add-char #\b 0)))

And with the definition:

(define add-char 
  (let ((ma (- (char->integer #\a))))
    (lambda (char num)
      (+ (char->integer char) ma num))))

(string-fold add-char 0 "abracadabra" 8) ; ==> 18

Now kons and knil is used in many SRFIs and very often in such combining situation. It does resemble the procedures cons and the name of '(). If you use those:

(string-fold cons '() "abracadabra" 8) ; ==
(cons #\a (cons #\r (cons #\b '())))   ; ==> (#\a #\r #\b)

Thus the names, while not random, is not needed to be understood in order to read and understand the SRFI. All other SRFIs have similar specifications. You might be interested in SRFI-9 Defining record types which has the following example:

(define-record-type :pare
  (kons x y)
  pare?
  (x kar set-kar!)
  (y kdr))

defines KONS to be a constructor, KAR and KDR to be accessors, SET-KAR! to be a modifier, and PARE? to be a predicate for :PAREs.

(pare? (kons 1 2))        --> #t
(pare? (cons 1 2))        --> #f
(kar (kons 1 2))          --> 1
(kdr (kons 1 2))          --> 2
(let ((k (kons 1 2)))
  (set-kar! k 3)
  (kar k))                --> 3
Sylwester
  • 47,942
  • 4
  • 47
  • 79