[racket] Signature for an optional-argument function?

From: Alexander D. Knauth (alexander at knauth.org)
Date: Fri Aug 23 16:17:41 EDT 2013

Thanks for the advice on signatures.

I'll try not to design functions as weird as that foo function (it was  
just a hypothetical example, not something that I think would be  
actually useful).

By the way for my fold function, I designed it so that (if you gave it  
the optional argument) it would behave like this:

(define (fold-with-cof comb cof base lox)
   (cond [(empty? lox) base]
         [else
          (comb (cof (first lox))
                (fold-with-cof comb cof base (rest lox)))]))

Because if the list contained non-primitive data then I would want a  
helper function there (where cof is), instead of trying to combine it  
or compose it with the combination function.  I made it so that it  
would behave exactly like foldr if cof was identity, but then when I  
figured out how to simulate the optional argument thing is ISL, I  
decided to design it so that you didn't even have to put identity there.

Also, what are some of the ways you can define variable-arity  
functions in Racket?  I know of one way:

(define (fold comb base lox [cof identity])
   (foldr comb base (map cof lox)))

But with this you have to put all the optional arguments last.  I  
wanted to put the cof argument between the comb and base arguments to  
remind myself that the comb function takes 2 arguments, the 1st of  
which is of the type that cof puts out, and the 2nd of which is the  
type of the base.  What other ways are there?

PS how different is Racket from ISL?  How hard would it be for me to  
learn Racket if I only know ISL and only started programming this  
summer?

On Aug 23, 2013, at 9:28 AM, Matthias Felleisen wrote:

>
> On Aug 23, 2013, at 12:28 AM, Alexander D. Knauth wrote:
>
>> Right now I'm using Intermediate Student Language, not Racket
>>
>> I was wondering if I could define a function with optional arguments
>
>
> In ISL+ you cannot defined variable-arity functions. In Racket there  
> are many mechanism for doing so (all reduced to one in the core  
> language). You can simulate the idea in ISL+, which you might have  
> done.
>
>
>> So how do I write the signature?
>
> In ISL+, that depends on how you simulate it. The best way is to  
> define a function that consumes a list of values but expects  
> specific kinds of values. For your flexible fold below, you could  
> write:
>
> ;; [List (X Y -> Y) (Z -> X) Y [List-of Z]]
> ;; or
> ;; [List (X Y -> Y) Y [List-of Z]]
> ;; ->  Y
>
> If you do not like 'or', introduce a separate data definition like  
> this:
>
> ;; [FoldArgument X Y Z] is one of:
> ;; -- [List (X Y -> Y) (Z -> X) Y [List-of Z]]
> ;; -- [List (X Y -> Y) Y [List-of Z]]
>
> and then you write
>
> ;; [FoldArgument X Y Z] -> Y
>
> In Racket, we tend to use square brackets in documentation. In  
> contracts -- a checked form of signature for module boundaries -- we  
> have a notation for this idea.
>
>
>> The particular example I'm thinking of is an abstract fold function  
>> that has an optional argument (a function) for the contribution of  
>> the first:
>> (check-expect (fold + 0 (list 1 2 3)) 6)           ;sum, without  
>> optional argument
>> (check-expect (fold + identity 0 (list 1 2 3)) 6)  ;sum, with  
>> identity as the optional argument
>> (check-expect (fold + string-length 0 (list "a" "bc" "def"))  
>> 6)  ;total-string-length
>>
>
> I would run your example as
>
>   (fold (compose + string-length) 0 '("a" ...))
>
> and be done.
>
>
>> You could also design a weird function that does completely  
>> different things depending on what the arguments are, like this:
>
> For fun, you can write any kind of function you like.
>
> As long as you design these functions to match the structure of the  
> data definition, your fellow programmers won't mind. Otherwise, they  
> will not like you. See my home page re 'psychopath'.
>
> -- Matthias
>
>
>
>
>
>
>
>
>
>
>


Greg Hendershott wrote:

> Although I don't recall for HtDP, the convention I've seen in Racket
> and docs generally is to use square brackets for an optional argument
> in the sense you mean: A single argument that's present or not. For
> instance:
>
> ;; ArgType [OptionalArgType] ArgType -> ResultType
>
> Whereas I would read "foo ..." as "zero or more": 0, 1, 2, .... +inf
>
> But your optional argument example is really "zero or one" (not more).
>
>
> A cheat sheet:
>
> Function/syntax sigs in docs:
> [zero-or-one]
> zero-or-more ...
>
> Regular expressions:
> zero-or-one?
> zero-or-more*
>
>
> p.s. When it comes to ONE-or-more in things like regexps, match
> patterns, macro syntax rules, and docs, there's more variety.
> Sometimes there's no explicit one-or-more notation so you have to
> "fake it" as:
>
> foo0 foo1 ...   ;; e.g. syntax-rules, syntax-case
>
> But sometimes you'll find notation like:
>
> foo+              ;; e.g. regexp
> foo ...+          ;; e.g. match, syntax-parse

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.racket-lang.org/users/archive/attachments/20130823/b5e1a1dc/attachment.html>

Posted on the users mailing list.