<html><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>Thanks for the advice on signatures. </div><div><br></div><div>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). </div><div><br></div><div>By the way for my fold function, I designed it so that (if you gave it the optional argument) it would behave like this:</div><div><br></div><div><font class="Apple-style-span" face="'Courier New'">(define (fold-with-cof comb cof base lox)</font></div><div><font class="Apple-style-span" face="'Courier New'"> (cond [(empty? lox) base]</font></div><div><font class="Apple-style-span" face="'Courier New'"> [else</font></div><div><font class="Apple-style-span" face="'Courier New'"> (comb (cof (first lox))</font></div><div><font class="Apple-style-span" face="'Courier New'"> (fold-with-cof comb cof base (rest lox)))]))</font></div><div><br></div><div>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. </div><div><br></div><div>Also, what are some of the ways you can define variable-arity functions in Racket? I know of one way:</div><div><br></div><div><font class="Apple-style-span" face="'Courier New'">(define (fold comb base lox [cof identity])</font></div><div><font class="Apple-style-span" face="'Courier New'"> (foldr comb base (map cof lox)))</font></div><div><br></div><div>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? </div><div><br></div><div>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? </div><br><div><div>On Aug 23, 2013, at 9:28 AM, Matthias Felleisen wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><br><div><div>On Aug 23, 2013, at 12:28 AM, Alexander D. Knauth wrote:</div><br class="Apple-interchange-newline"><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; ">Right now I'm using Intermediate Student Language, not Racket<div><br></div><div>I was wondering if I could define a function with optional arguments</div></div></blockquote><div><br></div><div><br></div><div>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. </div><div><br></div><div><br></div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div> So how do I write the signature? </div></div></blockquote><div><br></div><div>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: </div><div><br></div><div>;; [List (X Y -> Y) (Z -> X) Y [List-of Z]] </div><div>;; or</div><div>;; [List (X Y -> Y) Y [List-of Z]] </div><div>;; -> Y</div><div><br></div><div>If you do not like 'or', introduce a separate data definition like this: </div><div><br></div><div>;; [FoldArgument X Y Z] is one of: </div><div>;; -- [List (X Y -> Y) (Z -> X) Y [List-of Z]] </div><div>;; -- [List (X Y -> Y) Y [List-of Z]] </div><div><br></div><div>and then you write </div><div><br></div><div>;; [FoldArgument X Y Z] -> Y </div><div><br></div><div>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. </div><div><br></div><div><br></div><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div>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: </div><div style="font-family: Monaco; "><span class="Apple-style-span" style="font-family: Monaco; ">(check-expect (fold + 0 (list 1 2 3)) 6) ;sum, without optional argument</span></div><span class="Apple-style-span" style="font-family: Monaco; "><div><span class="Apple-style-span" style="font-family: Monaco; ">(check-expect (fold + identity 0 (list 1 2 3)) 6) ;sum, with identity as the optional argument</span></div></span><span class="Apple-style-span" style="font-family: Monaco; "><div><span class="Apple-style-span" style="font-family: Monaco; ">(check-expect (fold + string-length 0 (list "a" "bc" "def")) 6) ;total-string-length</span></div></span><span class="Apple-style-span" style="font-family: Monaco; "><span class="Apple-style-span" style="font-family: Monaco; "></span></span><span class="Apple-style-span" style="font-family: Monaco; "><div><br></div></span></div></blockquote><div><br></div><div>I would run your example as </div><div><br></div><div> (fold (compose + string-length) 0 '("a" ...)) </div><div><br></div><div>and be done. </div><div><br></div><br><blockquote type="cite"><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space; "><div><div>You could also design a weird function that does completely different things depending on what the arguments are, like this:</div></div></div></blockquote><br></div><div>For fun, you can write any kind of function you like. </div><div><br></div><div>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'. </div><div><br></div><div>-- Matthias</div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><div><br></div><br></div></blockquote></div><div><br></div>Greg Hendershott wrote:<div><br></div><div><blockquote type="cite">Although I don't recall for HtDP, the convention I've seen in Racket<br>and docs generally is to use square brackets for an optional argument<br>in the sense you mean: A single argument that's present or not. For<br>instance:<br><br>;; ArgType [OptionalArgType] ArgType -> ResultType<br><br>Whereas I would read "foo ..." as "zero or more": 0, 1, 2, .... +inf<br><br>But your optional argument example is really "zero or one" (not more).<br><br><br>A cheat sheet:<br><br>Function/syntax sigs in docs:<br>[zero-or-one]<br>zero-or-more ...<br><br>Regular expressions:<br>zero-or-one?<br>zero-or-more*<br><br><br>p.s. When it comes to ONE-or-more in things like regexps, match<br>patterns, macro syntax rules, and docs, there's more variety.<br>Sometimes there's no explicit one-or-more notation so you have to<br>"fake it" as:<br><br>foo0 foo1 ... ;; e.g. syntax-rules, syntax-case<br><br>But sometimes you'll find notation like:<br><br>foo+ ;; e.g. regexp<br>foo ...+ ;; e.g. match, syntax-parse<br></blockquote><br></div></body></html>