[racket] racket newbie question on quoting and the built in procedure-arity function
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 <matthias at 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 <matthias at 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 <samth at 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.shams at 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