Can we provide a list of functions?

42 views
Skip to first unread message

Yossu Bonkers

unread,
Jun 17, 2021, 9:37:54 AM6/17/21
to Racket Users
I'm quite new to racket, so please pardon me if this is a dumb question.

I'm working my way through the first tutorial in Beautiful Racket, and want to extend it. He only provides + and * as operators. I added support for others. 

The problem is that I need to specify the operators I support in two places, first where they are used in the handle function (see the highlighted line)...

(define (handle [arg #f])
  (cond
   [(number? arg) (push-stack! arg)] 
   [(or (equal? * arg) (equal? + arg))
     (define op-result (arg (pop-stack!) (pop-stack!))) 
     (push-stack! op-result)]))

..and then again when they are provided...


I was wondering if it would be possible to specify the supported operators in a list...

(define my-funs '(f1 f2))

...which could be used in handle, and then provide the functions in the list.

You can't simple do...

(provide my-funs)

...as this is a list of symbols. Equally you can't iterate the list and call provide on each member, as provide has to be a top-level function.

So, is there any way to provide the functions in the list?

Thanks

Jens Axel Søgaard

unread,
Jun 17, 2021, 10:21:36 AM6/17/21
to Yossu Bonkers, Racket Users

I'll give you the big picture. 

As you have observed, `provide` is a compile time construct and can't be used at runtime (where the list my-funs lives).
Since `provide` lives at compile time, the only solution is to use macros.

Define a macro, say, define-binary-function that can used as:

   (define-binary-function *)
   (define-binary-function +)

Given that, one can always define a define-binary-functions, that can be used as:

   (define-binary-functions + *)

and expands into multiple instances of define-binary-function.

Now, what must define-binary-function do?
It must: 
   1) expands to a provide of the function name
   2) add the function name to a list that holds names (symbols) of all binary functions.

You can accomplish 2) by having a global:

  (define all-binary-functions '())

and let define-binary-function expand to both a provide and to
  
  (set! all-binary-functions (cons 'id all-binary-functions))

where id is from the use (define-binary-function id).

In the definition of handle, you will then need to make use of all-binary-functions.


If you are familiar with macros, I hope the overview will give you a good start.
If not, the overview skipped a lot of details, so you will need to look at an 
introduction to macros first.

If you are interested, I'll be happy to send you a work-in-progress macro tutorial
I am working. I am always looking for feedback to make it better.

/Jens Axel





Yossu Bonkers

unread,
Jun 17, 2021, 12:26:17 PM6/17/21
to Racket Users
Wow, what a reply! Thanks.

As I said, I'm quite new to Racket, so haven't got my head around macros yet. I have a basic idea, but am not up to writing my own yet.

If you wouldn't mind showing me something, with some explanatory comments if you could, it would be great.

Thanks again

Reply all
Reply to author
Forward
0 new messages