Re: [racket-users] struct-copy question

2018-03-21 Thread Alexis King
> On Mar 21, 2018, at 15:32, Eric Griffis  wrote:
> 
> This would be a code smell if I didn't trust that our Racket ancestors
> knew what they were doing, so the notion of "fixing" structs (or even
> struct-copy) seems misguided.
> 
> [snip]
> 
> I can appreciate the architectural decision that structs represent for
> the core -- flexibility often comes with a cost to conciseness and
> convenience.

Without necessarily responding to all of your message, I think that it
would be an exaggeration to state that structs are the way they are
because they need to or ought to be that way. I was by no means using
Racket when most of the features that exist in the current struct system
were designed and implemented, but I believe I have heard or read it
said that certain choices are well-known to have been the wrong ones in
retrospect (#:transparent not being the default, for example).
Unfortunately, as you yourself say, they are used to represent nearly
everything in Racket, and redesigning them in a backwards-compatible way
is a daunting task.

On the one hand, I think Racket’s structures are fundamentally
challenging because they must accommodate dozens of use cases that are
necessary for Racket-the-platform but probably not directly relevant to
the majority of Racket programmers. For users, they would often like
them to be boring, plain old data types, but all sorts of other systems
need to be in place for other things to work. For example, they must be
chaperoneable/impersonatable in order for the contract system to work,
structure type properties exist to facilitate some sort of low-level
generic protocol mechanism, and structure inspectors allow privileged
tools to inspect the structure of “opaque” structures (though I’m not
actually sure what depends on this feature... DrRacket? ...the compiler
itself?).

On the other hand, certain things seem almost certainly incidentally
complex, like how the way the default printer prints structures is tied
to the structure’s inspector and how #:auto works. Generally, I think
#:auto is better avoided and replaced with your own wrapping
constructor, possibly using #:constructor-name to adjust the underlying
constructor name, but #:auto can’t be removed because Racket tries
pretty hard to never break backwards compatibility.

Alexis

P.S. Every so often someone kicks around the idea of “maybe we’ll fix
these things in a #lang racket2”, but that’s really just wishful
thinking at this point, given that I don’t believe anyone is working or
planning to work on implementing such a thing. Doing so is not trivial,
either, given that the two systems would need to be able to interoperate
to some extent.

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-21 Thread Eric Griffis
I bump into struct subtleties all the time. For example, my attempts to
#:auto always degenerate into custom constructor procedures; This usually
involves #:constructor-name and #:omit-define-syntaxes, which might not be
a big deal if I had a solid understanding of what these flags actually do.
So far, all of my struct troubles have been rooted in a lack of
understanding.

It is unfortunate that such a fundamental aspect can be so un-intuitive.
Reading the source hasn't helped much because structs are a low-level
construct used *everywhere* for *everything*. This would be a code smell if
I didn't trust that our Racket ancestors knew what they were doing, so the
notion of "fixing" structs (or even struct-copy) seems misguided.

Structs seem to occupy an awkward region of the design space between
totally opaque (e.g. objects) and totally transparent (e.g. algebraic data
types). On one hand, structs are too "open." The "good for everything"
design makes them not particularly great at anything. Prefabs are a
pathological case -- every attempt I've made at using them devolves into
lists or non-prefabs in order to re-gain control over basic things like
construction or printing. On the other hand, structs aren't "open" enough.
Racket's pattern-based binding forms allow me to de-structure, but it's not
yet clear to me how much extra plumbing would be needed for something like
a totality check, or even where that plumbing would go.

I can appreciate the architectural decision that structs represent for the
core -- flexibility often comes with a cost to conciseness and convenience.
For something like a standard library, where transparency prevents friction
between language users and implementers, I think higher-level abstractions
are more appropriate. My preference is for ADTs: they support a
pattern-based functional style, are amenable to static analysis and
automatic tooling, and I already have an intuition for how they should
behave.

/rant

Eric


On Tue, Mar 20, 2018 at 9:36 PM Kevin Forchione  wrote:

>
> Just read your GitHub link and see the problem goes beyond my simple
> #:auto issue. Thanks for that link. I’m pretty green to all the thorny
> issues when it comes to dressing primitive datatypes up in fancy bindings
> and hope the magicians of indirection can somehow pull a rabbit out of the
> hat on this one someday. :)
>
> Kevin
>
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-20 Thread Kevin Forchione

Just read your GitHub link and see the problem goes beyond my simple #:auto 
issue. Thanks for that link. I’m pretty green to all the thorny issues when it 
comes to dressing primitive datatypes up in fancy bindings and hope the 
magicians of indirection can somehow pull a rabbit out of the hat on this one 
someday. :) 

Kevin 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-20 Thread Kevin Forchione
On Mar 20, 2018, at 9:21 AM, Kevin Forchione  wrote:
> 
> 
Sorry, wrong example! 

>(struct fish (color (weight #:auto)) #:transparent)
>(define marlin (fish 'orange-and-white))
>(define dory (struct-copy fish marlin [color 'blue]))

../../Applications/Racket/collects/racket/private/define-struct.rkt:953:29: 
fish: arity mismatch;
 the expected number of arguments does not match the given number
  expected: 1
  given: 2
  arguments...:

Kevin
 

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-20 Thread Kevin Forchione

On Mar 19, 2018, at 2:35 PM, Alexis King  wrote:
> 
> I’m late to this thread, but perhaps I can clarify some things that I
> don’t think have been made entirely clear.
> 
> First of all, you are absolutely correct that structures, at runtime,
> know nothing whatsoever about field names. At runtime, structures are
> fancy vectors; the names provided for their fields just end up being
> used to generate accessor functions that look up values at the
> appropriate index.
> 
> So how do macros like match and struct-copy know what to do? Well, the
> struct macro creates a transformer binding that holds static information
> about the structure type, including the names of field accessors. As
> Eric already demonstrated, you can access that information using
> syntax-local-value combined with extract-struct-info, but that just
> produces a list containing an assortment of information.
> 
> There is a library that provides a struct-id syntax class that makes it
> easier to consume structure type transformer bindings:
> 
>  
> http://docs.racket-lang.org/syntax-classes/index.html#%28form._%28%28lib._syntax%2Fparse%2Fclass%2Fstruct-id..rkt%29._struct-id%29%29
>  
> 
> 
> It works with syntax/parse, and it defines attributes with names that
> handle the different sorts of things that can be produced by
> extract-struct-info. Disclaimer: I am the author of the library.
> 
> Finally, I am not sure about the particular issue with struct-copy and
> #:auto fields (which sounds fixable), but I think it is worth mentioning
> that struct-copy is irreparably broken and cannot be fixed without
> fundamental changes to Racket’s struct system. Namely, it has the
> “slicing” problem familiar to C++ programmers when using struct
> inheritance, and the way it synthesizes field accessors from the
> provided field names is unhygienic and can be easily thwarted. See this
> GitHub issue for more details:
> 
>  https://github.com/racket/racket/issues/1399 
> 
> 
> Alexis


Thanks, guys! This continues to be a very instructive exploration for me. The 
restructuring of struct (lol) sounds like something for a Racket 2? The issue I 
have with struct-copy is pretty easy to create: 

>(struct fish (color (weight #:auto)) #:transparent)
>(define marlin (fish 'orange-and-white 11))
>(define dory (struct-copy fish marlin [color 'blue]))

 fish: arity mismatch;
 the expected number of arguments does not match the given number
  expected: 1
  given: 2
  arguments…:

Kevin

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-19 Thread Alexis King
I’m late to this thread, but perhaps I can clarify some things that I
don’t think have been made entirely clear.

First of all, you are absolutely correct that structures, at runtime,
know nothing whatsoever about field names. At runtime, structures are
fancy vectors; the names provided for their fields just end up being
used to generate accessor functions that look up values at the
appropriate index.

So how do macros like match and struct-copy know what to do? Well, the
struct macro creates a transformer binding that holds static information
about the structure type, including the names of field accessors. As
Eric already demonstrated, you can access that information using
syntax-local-value combined with extract-struct-info, but that just
produces a list containing an assortment of information.

There is a library that provides a struct-id syntax class that makes it
easier to consume structure type transformer bindings:

  
http://docs.racket-lang.org/syntax-classes/index.html#%28form._%28%28lib._syntax%2Fparse%2Fclass%2Fstruct-id..rkt%29._struct-id%29%29

It works with syntax/parse, and it defines attributes with names that
handle the different sorts of things that can be produced by
extract-struct-info. Disclaimer: I am the author of the library.

Finally, I am not sure about the particular issue with struct-copy and
#:auto fields (which sounds fixable), but I think it is worth mentioning
that struct-copy is irreparably broken and cannot be fixed without
fundamental changes to Racket’s struct system. Namely, it has the
“slicing” problem familiar to C++ programmers when using struct
inheritance, and the way it synthesizes field accessors from the
provided field names is unhygienic and can be easily thwarted. See this
GitHub issue for more details:

  https://github.com/racket/racket/issues/1399

Alexis

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-19 Thread Eric Griffis
Does this help?

```
(define-syntax (dump-struct-info stx)
  (syntax-case stx ()
[(_ info)
 (pretty-write
  `(GOT ,(extract-struct-info (syntax-local-value #'info (λ () #f)
 #'(void)]))
```

Then we can do:

```
> (struct point (x y [z #:auto #:mutable]) #:transparent)
> (dump-struct-info point)
(GOT
 (#
  #
  #
  (# # #)
  (# #f #f)
  #t))
```

Eric


On Sat, Mar 17, 2018 at 8:15 PM Kevin Forchione  wrote:

>
>
> > On Mar 17, 2018, at 9:24 AM, Eric Griffis  wrote:
> >
> > How about a list of identifiers bound to getters or setters? The
> `extract-struct-info` procedure in Section 5.7 of the Racket Reference
> appears to give you that.
> >
> > Eric
>
> Souned promising, but  it sounds like you have to roll a struct-info
> first, unless I’ve missed something. I did have some fun exploring 5.2
> Creating Structure Types (the link to Examples for
> make-struct-field-accessor & make-struct-field-mutaor appear to lead you
> back to the top of the page, but as far as I can tell there are no examples
> there for those functions…)
>
>

> No, what I was hoping for was something you could throw a structure
> instance at and obtains a list of its accessors/mutators so that I could
> then write a generalized version of struct-copy (which appears not to copy
> a struct that has #:auto fields. Placing a struct inside of  a define
> though gives a pretty quick glimpse at the underlying code that the (struct
> ….) generates, and the mutator created by make-struct-type is simply thrown
> away (when not used by make-struct-mutator. I would think that between that
> (if it could be retained) and the struct->list function, which produces an
> index-ordered list of the struct’s values, that you could create a
> struct-copy that would populate all of the fields. Of course, you’d have a
> mutator out in the wild that could always modify the struct… no, you’d have
> to encapsulate all that into a special function foo-copy for struct foo,
> and pass that out with the mutator safely encapsulated in a lambda, I
> supposed
>
> Kevin

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-17 Thread Kevin Forchione


> On Mar 17, 2018, at 9:24 AM, Eric Griffis  wrote:
> 
> How about a list of identifiers bound to getters or setters? The 
> `extract-struct-info` procedure in Section 5.7 of the Racket Reference 
> appears to give you that.
> 
> Eric

Souned promising, but  it sounds like you have to roll a struct-info first, 
unless I’ve missed something. I did have some fun exploring 5.2 Creating 
Structure Types (the link to Examples for make-struct-field-accessor & 
make-struct-field-mutaor appear to lead you back to the top of the page, but as 
far as I can tell there are no examples there for those functions…) 

No, what I was hoping for was something you could throw a structure instance at 
and obtains a list of its accessors/mutators so that I could then write a 
generalized version of struct-copy (which appears not to copy a struct that has 
#:auto fields. Placing a struct inside of  a define though gives a pretty quick 
glimpse at the underlying code that the (struct ….) generates, and the mutator 
created by make-struct-type is simply thrown away (when not used by 
make-struct-mutator. I would think that between that (if it could be retained) 
and the struct->list function, which produces an index-ordered list of the 
struct’s values, that you could create a struct-copy that would populate all of 
the fields. Of course, you’d have a mutator out in the wild that could always 
modify the struct… no, you’d have to encapsulate all that into a special 
function foo-copy for struct foo, and pass that out with the mutator safely 
encapsulated in a lambda, I supposed

Kevin

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-17 Thread Eric Griffis
How about a list of identifiers bound to getters or setters? The
`extract-struct-info` procedure in Section 5.7 of the Racket Reference
appears to give you that.

Eric


On Fri, Mar 16, 2018 at 2:56 PM Kevin Forchione  wrote:

>
>
> > On Mar 16, 2018, at 2:38 PM, Kevin Forchione  wrote:
> >
> > Hi guys,
> > I’ve noticed that struct-copy doesn’t appear to work when fields are
> defined with #:auto. So this leads to my question, which may not be
> answerable since it would presumably be used to fix struct-copy, but is
> there a way to retrieve a list of struct fields for a struct? I have a
> feeling there is some macro work going on and that the struct isn’t really
> “aware” of its field names. If that’s the case, wouldn’t it be interesting
> if the macro included building a function that would return these names as
> a symbols list? :)
>
> Actually, what wold be interesting would be a list of lists, containing
> the getters and setters for the struct. :)
>
> Kevin
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to racket-users+unsubscr...@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.
>

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [racket-users] struct-copy question

2018-03-16 Thread Kevin Forchione


> On Mar 16, 2018, at 2:38 PM, Kevin Forchione  wrote:
> 
> Hi guys, 
> I’ve noticed that struct-copy doesn’t appear to work when fields are defined 
> with #:auto. So this leads to my question, which may not be answerable since 
> it would presumably be used to fix struct-copy, but is there a way to 
> retrieve a list of struct fields for a struct? I have a feeling there is some 
> macro work going on and that the struct isn’t really “aware” of its field 
> names. If that’s the case, wouldn’t it be interesting if the macro included 
> building a function that would return these names as a symbols list? :) 

Actually, what wold be interesting would be a list of lists, containing the 
getters and setters for the struct. :) 

Kevin

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


[racket-users] struct-copy question

2018-03-16 Thread Kevin Forchione
Hi guys, 
I’ve noticed that struct-copy doesn’t appear to work when fields are defined 
with #:auto. So this leads to my question, which may not be answerable since it 
would presumably be used to fix struct-copy, but is there a way to retrieve a 
list of struct fields for a struct? I have a feeling there is some macro work 
going on and that the struct isn’t really “aware” of its field names. If that’s 
the case, wouldn’t it be interesting if the macro included building a function 
that would return these names as a symbols list? :) 

Thanks, 
Kevin

-- 
You received this message because you are subscribed to the Google Groups 
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to racket-users+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.