3

For a structure and its instance defined as follows:

(struct dog (name breed age))  
(define mydog (dog "lassie" "collie" 5))

(example from https://learnxinyminutes.com/docs/racket/)

The usual way to get a structure field is as follows:

(dog-name mydog) ; => "lassie"

Can there be a macro so that we can perform above using following dot notation:

(mydog.name) ; => "lassie" 

Or, parentheses may not be needed:

mydog.name ; => "lassie" 

Macro for dot notation is used on this page: http://www.greghendershott.com/fear-of-macros/pattern-matching.html#%28part._hash..refs%29 but I am not able to use it for above purpose. I also saw some details of structure macro on this page: Is struct a macro in Racket?

Edit: as suggested in comments and as mentioned on https://docs.racket-lang.org/reference/reader.html?q=read-cdot#%28part._parse-cdot%29, I tried read-cdot, but it does not work:

#lang racket
(read-cdot #t) 
(struct dog (name breed age))  
(define mydog (dog "lassie" "collie" 5))
(dog-name mydog) ; works
mydog.dog-name   ; does not work; 

The error is:

 mydog.dog-name: unbound identifier in module in: mydog.dog-name
Community
  • 1
  • 1
rnso
  • 23,686
  • 25
  • 112
  • 234
  • 1
    One package that provides some sugary notation is [`postfix-dot-notation`](http://docs.racket-lang.org/postfix-dot-notation/index.html), which translates `mydog.dog-name` into `(dog-name mydog)`. All it does is translate `a.f` into `(f a)`. Also I think Jay McCarthy is planning on making a dot notation part of his `remix` language, but it's not ready for use yet. – Alex Knauth Aug 25 '16 at 12:38
  • How to write a macro to convert a.f to (f a)? I am not able to use regex in the macro procedures to detect dot and split the term to rearrange the parts. – rnso Aug 25 '16 at 12:41
  • 1
    If you write a reader-level extension, you could take advantage of the [`read-cdot`](http://docs.racket-lang.org/reference/Reading.html#%28def._%28%28quote._~23~25kernel%29._read-cdot%29%29) option. The behavior it triggers is described in [Reading with C-style infix dot notation](http://docs.racket-lang.org/reference/reader.html#%28part._parse-cdot%29) – Alex Knauth Aug 25 '16 at 12:47
  • "#lang postfix-dot-notation" is not working in drracket: standard-module-name-resolver: collection not found – rnso Aug 25 '16 at 13:02
  • You need to install the `postfix-dot-notation` package first. Go to the File menu in DrRacket, click on Package Manager, and enter `postfix-dot-notation` in the Package Source field. – Alex Knauth Aug 25 '16 at 13:11
  • Yes, it works. Is the macro for this very complicated? – rnso Aug 25 '16 at 13:55
  • The implementation of the reader extension is in [this file](https://github.com/AlexKnauth/postfix-dot-notation/blob/master/postfix-dot-notation/reader.rkt) if you're interested in how it works. Although it itself should probably be updated to use the `read-cdot` option instead. – Alex Knauth Aug 25 '16 at 14:10
  • Does it work for class (object) functions also? Will "my-object.my-public-fn" work? The examples on http://docs.racket-lang.org/postfix-dot-notation/index.html are only for structures. – rnso Aug 25 '16 at 14:15
  • They will only work if you do something like `(define ((my-public-method obj) . args) (send/apply obj my-public-method args))` for every method you want to use this way. So no, but you can pretend. – Alex Knauth Aug 25 '16 at 14:33
  • Can I write a macro to simply convert (a.b x ...) to (send a b x ...) ? – rnso Aug 25 '16 at 15:00
  • 1
    To use `read-cdot` for this, you will need two things. One, a reader-level extension to turn it on, and Two, a `#%dot` macro. For the reader-level extension the easiest thing will be to use [`#lang s-exp syntax/module-reader`](http://docs.racket-lang.org/syntax/reader-helpers.html#%28mod-path._syntax%2Fmodule-reader%29) with the `#:wrapper1` option. The `wrapper1-expr` will look something like `(lambda (thunk) (parameterize ([read-cdot #true]) (thunk)))`. There's an example in the docs where it describes what `#:wrapper1` does. – Alex Knauth Aug 26 '16 at 04:19
  • 1
    Actually, DON'T USE `read-cdot`. It is completely broken right now, and I've submitted a bug report. – Alex Knauth Aug 26 '16 at 04:55
  • 1
    You could write a macro to define all the `name.field` identifiers -- same for `send`. http://pasterack.org/pastes/61417 – Ben Greenman Aug 26 '16 at 21:00
  • The `read-cdot` bug has been fixed now in the [latest snapshot version](https://pre.racket-lang.org/) of racket. I'll use it to answer your other question about using it as a shorthand for `send` on `racket/class` objects. – Alex Knauth Aug 30 '16 at 13:34

0 Answers0