Rian, you want a syntactic abstraction that hides this mechanism:
#lang racket (module library racket (provide ;; syntax ;; (define/safe (f x ...) e ...) ;; introduces a safe function that is ... and prints its name as just 'f' define/safe) (define-syntax-rule (define/safe (f x ...) e ...) (define f (safe-function (lambda (x ...) e ...) 'f))) (struct safe-function (f name) #:property prop:procedure 0 ; first field is the function #:methods gen:custom-write [(define (write-proc safe-function port mode) (display (safe-function-name safe-function) port))])) (module sample-tester racket (require (submod ".." library)) (module+ test (require rackunit)) (define/safe ($+ x ...) (+ x ...)) (module+ test (check-equal? ($+ 3 4) 7) (check-equal? (with-output-to-string (write $+)) "$+"))) (require 'sample-tester) On Jan 6, 2014, at 9:26 AM, Vincent St-Amour <stamo...@ccs.neu.edu> wrote: > As far as I know, no. > > Vincent > > > At Sun, 5 Jan 2014 19:51:10 -0500, > Rian Shams wrote: >> >> Perfect, I didn't know structs could be used like that. >> Thank you! >> >> As a follow-up question, can you directly create functions with a custom >> printing method, without having to go through structs? >> >> >> On Sat, Jan 4, 2014 at 8:13 PM, Vincent St-Amour <stamo...@ccs.neu.edu>wrote: >> >>> Similarly, you can represent safe functions as applicable structures (so >>> they can behave like functions) with a custom printing method. >>> >>> #lang racket >>> >>> (struct safe-function (f name) >>> #:property prop:procedure 0 ; first field is the function >>> #:methods gen:custom-write >>> [(define (write-proc safe-function port mode) >>> (display (safe-function-name safe-function) port))]) >>> >>> (define $+ (safe-function + '$+)) >>> >>> ($+ 1 2) ; => 3 >>> $+ ; prints "$+" >>> >>> >>> Vincent >>> >>> >>> >>> At Sat, 4 Jan 2014 18:52:55 -0500, >>> Matthias Felleisen wrote: >>>> >>>> [1 <multipart/alternative (7bit)>] >>>> [1.1 <text/plain; iso-8859-1 (quoted-printable)>] >>>> >>>> Perhaps you want something like this: >>>> >>>> Welcome to Racket v6.0.0.1. >>>>> (current-print (lambda (x) (if (procedure? x) (printf "~a" >>> (object-name x)) (print x)) (newline))) >>>> #<void> >>>>> + >>>> + >>>>> 10 >>>> 10 >>>> >>>> >>>> >>>> >>>> On Jan 4, 2014, at 6:40 PM, Rian Shams wrote: >>>> >>>>> Sorry for my lack of clarity. >>>>> >>>>> My question is about the output that is displayed from calling the >>> function. For example, evaluating just >>>>> >>>>>> $+ >>>>> #<procedure:$+> >>>>> >>>>> The result I am looking for is >>>>> >>>>>> $+ >>>>> $+ >>>>> >>>>> as opposed to >>>>> #<procedure:$+> >>>>> >>>>> I am not sure whether this is just a formatting or renaming problem, >>> or if it is possible to change what the interpreter displays in Dr.Racket? >>>>> >>>>> I am fairly new to Racket and programming in general and so I really >>> appreciate your responses and patience. >>>>> >>>>> >>>>> On Sat, Jan 4, 2014 at 5:49 PM, Matthias Felleisen < >>> matth...@ccs.neu.edu> wrote: >>>>> >>>>> Yes, you need two functions: one that gives you the name of a >>> procedure and one that picks a procedure. I was merely hinting at how to do >>> the former. -- Matthias >>>>> >>>>> >>>>> >>>>> On Jan 4, 2014, at 4:57 PM, Rian Shams wrote: >>>>> >>>>>> Thanks Matthias, >>>>>> >>>>>> If I use your definition: >>>>>> >>>>>> (define (select-random-safe-function) >>>>>> (object-name >>>>>> (list-ref safe-function-set (random (length safe-function-set))))) >>>>>> >>>>>> then, >>>>>> >>>>>>> (procedure-arity (select-random-safe-function)) >>>>>> error:procedure-arity: contract violation >>>>>> expected: procedure? >>>>>> given: '$+ >>>>>> >>>>>> >>>>>> I believe I need two things: >>>>>> >>>>>> 1. (select-random-safe-function) should return an unquoted procedure, >>> similar to >>>>>> >>>>>> (define (select-random-safe-function) ;without object-name >>>>>> (list-ref safe-function-set (random (length safe-function-set)))) >>>>>>> (select-random-safe-function) >>>>>> #<procedure:$+> >>>>>> >>>>>> preferably without #<procedure: $+ > >>>>>> >>>>>> so my problem is that I want the output to display >>>>>> $+ >>>>>> instead of >>>>>> #<procedure:$+> >>>>>> >>>>>> 2. The reason the procedure needs to be unquoted is because >>>>>> (procedure-arity (select-random-safe-function)) will produce an error >>> if the function is quoted. >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> Later on I use both (procedure-arity (select-random-safe-function)) >>> and (select-random-safe-function) in a main function: >>>>>> >>>>>> ;;Generate Initial Population >>>>>> ;population size is a positive integer and the auxiliary-function, >>> generate-chromsome generates a tree using functions from safe-function-set >>> and terms (numbers and symbols) from a term-set >>>>>> >>>>>> (define (generate-initial-population population-size) >>>>>> (cond [(zero? population-size) empty] >>>>>> [else (cons (generate-chromosome initial-chromosome-depth) >>> ;initial-chromosome-depth is 3 >>>>>> (generate-initial-population (sub1 >>> population-size)))])) >>>>>> >>>>>>> (generate-initial-population 1) >>>>>> '((#<procedure:$/> (#<procedure:$-> x .234) (#<procedure:$+> .576 x))) >>>>>> >>>>>> this gets me my desired result, but is hard for me to read especially >>> as the depth and population size grows (typically I will be working with >>> populations ranging in the hundreds or thousands and each chromosome/tree's >>> depth could easily exceed 10) so it would be more convenient here if my >>> solution displays >>>>>> >>>>>> '(($/ ($- x .234) ($+ .576 x))) >>>>>> >>>>>> instead of >>>>>> >>>>>> '((#<procedure:$/> (#<procedure:$-> x .234) (#<procedure:$+> .576 x))) >>>>>> >>>>>> and I am not sure how I would go about doing this? >>>>>> >>>>>> On Sat, Jan 4, 2014 at 8:45 AM, Matthias Felleisen < >>> matth...@ccs.neu.edu> wrote: >>>>>> >>>>>> If you really just want the name, use object-name: >>>>>> >>>>>> (define (select-random-safe-function) >>>>>> (object-name >>>>>> (list-ref safe-function-set (random (length safe-function-set))))) >>>>>> >>>>>> Welcome to DrRacket, version 6.0.0.1--2013-12-29(bbb0c5f6/d) [3m]. >>>>>> Language: racket. >>>>>>> (select-random-safe-function) >>>>>> '$* >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> On Jan 4, 2014, at 2:48 AM, Rian Shams wrote: >>>>>> >>>>>>> If I do this I get the results I need for (procedure-arity >>> (select-random-safe-function)), but when I call >>>>>>> (safe-function-set) or (select-random-safe-function) or any other >>> function that returns a safe function I get for example: >>>>>>> >>>>>>>> (safe-function-set) >>>>>>> '(#<procedure:$+> #<procedure:$-> #<procedure:$*> #<procedure:$/>) >>>>>>> >>>>>>>> (select-random-safe-function) >>>>>>> #<procedure:$-> >>>>>>> >>>>>>> whereas when it was defined using quote as opposed to list I get: >>>>>>> >>>>>>>> (safe-function-set) >>>>>>> '($+ $- $* $/) >>>>>>> >>>>>>>> (select-random-safe-function) >>>>>>> '$- >>>>>>> >>>>>>> How would I get rid of this #<procedure:$-> part for readability, >>> keeping only the $- part which is the actual function I defined, while >>> still keeping it a function/procedure that gives me the function arity >>> using (procedure-arity (select-random-safe-function))? >>>>>>> >>>>>>> Best, >>>>>>> >>>>>>> >>>>>>> On Fri, Jan 3, 2014 at 5:31 PM, Sam Tobin-Hochstadt < >>> sa...@cs.indiana.edu> wrote: >>>>>>> Try replacing `safe-function-set` with: >>>>>>> >>>>>>> (define safe-function-set (list $+ $- $* $/)) >>>>>>> >>>>>>> Sam >>>>>>> >>>>>>> On Fri, Jan 3, 2014 at 5:28 PM, Rian Shams <rian.sh...@gmail.com> >>> wrote: >>>>>>>> Hello, >>>>>>>> >>>>>>>> I am working with functions that I have defined to only take 1 or >>> 2 operands >>>>>>>> (called safe-functions) for the implementation of a genetic >>> program. >>>>>>>> >>>>>>>> (define ($+ augend addend) ;operation is addition >>>>>>>> (+ augend addend)) ; the result is the sum >>>>>>>> (define ($- minuend subtrahend) ;operation is subtraction >>>>>>>> (- minuend subtrahend)) ;result is difference >>>>>>>> (define ($* multiplicand multiplier) ;operation is multiplication >>>>>>>> (* multiplicand multiplier)) ;result is product >>>>>>>> (define ($/ dividend divisor) ;operation is division >>>>>>>> (/ dividend divisor)) ;result is quotient >>>>>>>> >>>>>>>> (define (infinity? x) (or (eq? x +Inf.0) (eq? x -Inf.0))) >>>>>>>> (define ($sin x) (if (infinity? x) (* (sgn x) +Inf.0) (sin x))) >>>>>>>> (define ($cos x) (if (infinity? x) (* (sgn x) +Inf.0) (cos x))) >>>>>>>> >>>>>>>> (define safe-function-set >>>>>>>> '($+ >>>>>>>> $- >>>>>>>> $* >>>>>>>> $/ >>>>>>>> ;$sin >>>>>>>> ;$cos)) >>>>>>>> >>>>>>>> (define (select-random-safe-function) >>>>>>>> (list-ref safe-function-set (random (length safe-function-set)))) >>>>>>>> >>>>>>>> I would like to use procedure-arity (or a similar function) to >>> determine the >>>>>>>> arity of a randomly selected safe function but I get this error: >>>>>>>> >>>>>>>>> (procedure-arity (select-random-safe-function)) >>>>>>>> error: procedure-arity: contract violation >>>>>>>> expected: procedure? >>>>>>>> given: '$+ >>>>>>>> >>>>>>>> I think the problem is that the safe-functions are passed to >>> procedure-arity >>>>>>>> quoted. Is there a way I can unquote the functions, or adjust >>>>>>>> procedure-arity to make (procedure-arity >>> (select-random-safe-function)) >>>>>>>> work? >>>>>>>> >>>>>>>> Thanks, >>>>>>>> -- >>>>>>>> Rian Shams >>>>>>>> >>>>>>>> ____________________ >>>>>>>> Racket Users list: >>>>>>>> http://lists.racket-lang.org/users >>>>>>>> >>>>>>> >>>>>>> >>>>>>> >>>>>>> -- >>>>>>> Rian Shams >>>>>>> ____________________ >>>>>>> Racket Users list: >>>>>>> http://lists.racket-lang.org/users >>>>>> >>>>>> >>>>>> >>>>>> >>>>>> -- >>>>>> Rian Shams >>>>> >>>>> >>>>> >>>>> >>>>> -- >>>>> Rian Shams >>>> >>>> [1.2 <text/html; iso-8859-1 (7bit)>] >>>> >>>> [2 <text/plain; us-ascii (7bit)>] >>>> ____________________ >>>> Racket Users list: >>>> http://lists.racket-lang.org/users >>> >> >> >> >> -- >> Rian Shams >> [2 <text/html; ISO-8859-1 (quoted-printable)>] >> ____________________ Racket Users list: http://lists.racket-lang.org/users