Re: [racket-dev] Generics updates

2013-10-04 Thread Matthias Felleisen

On Oct 2, 2013, at 4:41 PM, Sam Tobin-Hochstadt wrote:

 I think I prefer separate unrelated data structures,


+1 


We need to look at other languages and what devs 
say about intermingling and/or separating applicative
and stateful data types. Java and Scala seem to provide
particularly bad examples, so perhaps we should not follow
what they do :-) 

-- Matthias

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-10-04 Thread Sam Tobin-Hochstadt
On Fri, Oct 4, 2013 at 1:30 PM, Matthias Felleisen matth...@ccs.neu.edu wrote:
 Java and Scala seem to provide
 particularly bad examples, so perhaps we should not follow
 what they do :-)

I know what you mean about Java, but I've heard lots of good things
about the new Scala collections framework.  Is there something
specific you're thinking about?

Sam
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-10-02 Thread J. Ian Johnson
This means I can't interchange between mutable and immutable sets for my 
functions that only need to read generic sets, unless we further subdivide and 
have gen:set-query gen:set-constructor gen:set-mconstruct.

-Ian
- Original Message -
From: Jay McCarthy jay.mccar...@gmail.com
To: Carl Eastlund c...@ccs.neu.edu
Cc: Racket Developers dev@racket-lang.org
Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada Eastern
Subject: Re: [racket-dev] Generics updates

Regarding a point from RacketCon, I don't like that gen:set includes
functions like set-add! and set-remove!. I think that sets with
mutations are subclass of get:set and we should have a separate
gen:mset (or something) interface for mutable versions.

I dislike that an obvious implementation of sets, hash tables, are not
sets to gen:set, because there are operations that cannot be performed
on them.

I think that X implements generic G should imply All functions of G
work on X. But this is not the case with gen:set and hasheq sets, for
instance.

Jay


On Tue, Jul 23, 2013 at 9:37 AM, Carl Eastlund c...@ccs.neu.edu wrote:
 My work on adding gen:set, and related changes to define-generics and
 gen:dict, is ready for review and (hopefully) to push to the master branch.
 The branch moved in the process of cleaning things up, it's now at:

   https://github.com/carl-eastlund/racket/tree/generics-from-scratch

 (The from scratch just refers to the process of rebuilding the git
 history, I didn't go out of my way to rewrite anything in the code base from
 scratch, although in some places a lot of code did move around.)

 What's new in the branch:

 - Generics now support a few new options
   - #:fallbacks specifies fallback method implementations for instances with
 no implementation
   - #:fast-defaults specifies instances on a fast path, useful for
 built-in types
   - #:defined-predicate gives a more intuitive and efficient interface than
 #:defined-table
   - #:derive-property allows generics to piggy-back on existing struct
 properties

 - Sets are now a generic datatype through gen:set
   - lists are now sets
   - the built-in set types are now documented as hash sets
   - there are mutable and weak hash sets
   - you can define new set types quickly with define-custom-set-types
   - most set operations are now methods with fallbacks
   - sets now support -copy and -clear operations, plus mutating [!] versions
 of operations

 - Dictionaries have a few changes
   - new macro define-custom-hash-types [*]
   - most dict operations are now methods with fallbacks
   - dicts now support -copy, -clear, -clear!, and -empty? operations

 I've run some benchmarks and performance of the various generic operations
 are comparable to the current HEAD, so there should be no major performance
 changes with this patch.

 [*] I've added define-custom-hash-types and define-custom-set-types rather
 than just adding make-custom-set akin to make-custom-hash because
 make-custom-hash is hard to use.  The documented behavior -- that any custom
 hash is equal to any other created with the same bindings and predicates /
 hash functions -- was never true and can be expensive or at least tricky to
 implement.  It seemed more sensible to just remove the erroneous
 documentation on make-custom-hash, and add the definition form to create
 constructors for new, explicitly-compatible dict and set types.  Both
 definition forms bind predicates and constructors for new (set or dict)
 types with immutable, mutable, and weak variants that inter-operate.

 If there are no serious issues brought up in the next day or two, I'll push
 it to the development branch, since our current release process isn't
 following HEAD.

 Carl Eastlund

 _
   Racket Developers list:
   http://lists.racket-lang.org/dev




-- 
Jay McCarthy j...@cs.byu.edu
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

The glory of God is Intelligence - DC 93
_
  Racket Developers list:
  http://lists.racket-lang.org/dev
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-10-02 Thread Jay McCarthy
No. Mutable sets would implement gen:set and then just have a few more
methods in the gen:mset interface. Structs can implement any number of
generics.

Jay

On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu wrote:
 This means I can't interchange between mutable and immutable sets for my 
 functions that only need to read generic sets, unless we further subdivide 
 and have gen:set-query gen:set-constructor gen:set-mconstruct.

 -Ian
 - Original Message -
 From: Jay McCarthy jay.mccar...@gmail.com
 To: Carl Eastlund c...@ccs.neu.edu
 Cc: Racket Developers dev@racket-lang.org
 Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada Eastern
 Subject: Re: [racket-dev] Generics updates

 Regarding a point from RacketCon, I don't like that gen:set includes
 functions like set-add! and set-remove!. I think that sets with
 mutations are subclass of get:set and we should have a separate
 gen:mset (or something) interface for mutable versions.

 I dislike that an obvious implementation of sets, hash tables, are not
 sets to gen:set, because there are operations that cannot be performed
 on them.

 I think that X implements generic G should imply All functions of G
 work on X. But this is not the case with gen:set and hasheq sets, for
 instance.

 Jay


 On Tue, Jul 23, 2013 at 9:37 AM, Carl Eastlund c...@ccs.neu.edu wrote:
 My work on adding gen:set, and related changes to define-generics and
 gen:dict, is ready for review and (hopefully) to push to the master branch.
 The branch moved in the process of cleaning things up, it's now at:

   https://github.com/carl-eastlund/racket/tree/generics-from-scratch

 (The from scratch just refers to the process of rebuilding the git
 history, I didn't go out of my way to rewrite anything in the code base from
 scratch, although in some places a lot of code did move around.)

 What's new in the branch:

 - Generics now support a few new options
   - #:fallbacks specifies fallback method implementations for instances with
 no implementation
   - #:fast-defaults specifies instances on a fast path, useful for
 built-in types
   - #:defined-predicate gives a more intuitive and efficient interface than
 #:defined-table
   - #:derive-property allows generics to piggy-back on existing struct
 properties

 - Sets are now a generic datatype through gen:set
   - lists are now sets
   - the built-in set types are now documented as hash sets
   - there are mutable and weak hash sets
   - you can define new set types quickly with define-custom-set-types
   - most set operations are now methods with fallbacks
   - sets now support -copy and -clear operations, plus mutating [!] versions
 of operations

 - Dictionaries have a few changes
   - new macro define-custom-hash-types [*]
   - most dict operations are now methods with fallbacks
   - dicts now support -copy, -clear, -clear!, and -empty? operations

 I've run some benchmarks and performance of the various generic operations
 are comparable to the current HEAD, so there should be no major performance
 changes with this patch.

 [*] I've added define-custom-hash-types and define-custom-set-types rather
 than just adding make-custom-set akin to make-custom-hash because
 make-custom-hash is hard to use.  The documented behavior -- that any custom
 hash is equal to any other created with the same bindings and predicates /
 hash functions -- was never true and can be expensive or at least tricky to
 implement.  It seemed more sensible to just remove the erroneous
 documentation on make-custom-hash, and add the definition form to create
 constructors for new, explicitly-compatible dict and set types.  Both
 definition forms bind predicates and constructors for new (set or dict)
 types with immutable, mutable, and weak variants that inter-operate.

 If there are no serious issues brought up in the next day or two, I'll push
 it to the development branch, since our current release process isn't
 following HEAD.

 Carl Eastlund

 _
   Racket Developers list:
   http://lists.racket-lang.org/dev




 --
 Jay McCarthy j...@cs.byu.edu
 Assistant Professor / Brigham Young University
 http://faculty.cs.byu.edu/~jay

 The glory of God is Intelligence - DC 93
 _
   Racket Developers list:
   http://lists.racket-lang.org/dev



-- 
Jay McCarthy j...@cs.byu.edu
Assistant Professor / Brigham Young University
http://faculty.cs.byu.edu/~jay

The glory of God is Intelligence - DC 93
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-10-02 Thread Jay McCarthy
Even if we were to remove set-add! from gen:set and not great gen:mset
then that would not be a vaild property. Generics are a lower bound on
the interface, not an upper bound, so there could be other functions
on the data structure that implement mutation. For instance, a gen:set
could be made for an external resource that was set-like.

I think what you want is something like gen:fset that has no methods,
but is used for set authors to tag their set as having this property
for the benefit of consumers (which cannot be enforced.) Your library
would then consume fsets and not sets.

Jay


On Wed, Oct 2, 2013 at 2:09 PM, Robby Findler
ro...@eecs.northwestern.edu wrote:
 If we do go this way, we should be careful about the subtyping relationship
 since we want a predicate that means will not be mutated and I can rely on
 that to reason about my library's behavior and if mutable sets are a
 sub-thing of immutable ones, we might lose that (depending on how things are
 set up).

 Robby


 On Wed, Oct 2, 2013 at 2:57 PM, Jay McCarthy jay.mccar...@gmail.com wrote:

 No. Mutable sets would implement gen:set and then just have a few more
 methods in the gen:mset interface. Structs can implement any number of
 generics.

 Jay

 On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu wrote:
  This means I can't interchange between mutable and immutable sets for my
  functions that only need to read generic sets, unless we further subdivide
  and have gen:set-query gen:set-constructor gen:set-mconstruct.
 
  -Ian
  - Original Message -
  From: Jay McCarthy jay.mccar...@gmail.com
  To: Carl Eastlund c...@ccs.neu.edu
  Cc: Racket Developers dev@racket-lang.org
  Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada Eastern
  Subject: Re: [racket-dev] Generics updates
 
  Regarding a point from RacketCon, I don't like that gen:set includes
  functions like set-add! and set-remove!. I think that sets with
  mutations are subclass of get:set and we should have a separate
  gen:mset (or something) interface for mutable versions.
 
  I dislike that an obvious implementation of sets, hash tables, are not
  sets to gen:set, because there are operations that cannot be performed
  on them.
 
  I think that X implements generic G should imply All functions of G
  work on X. But this is not the case with gen:set and hasheq sets, for
  instance.
 
  Jay
 
 
  On Tue, Jul 23, 2013 at 9:37 AM, Carl Eastlund c...@ccs.neu.edu wrote:
  My work on adding gen:set, and related changes to define-generics and
  gen:dict, is ready for review and (hopefully) to push to the master
  branch.
  The branch moved in the process of cleaning things up, it's now at:
 
https://github.com/carl-eastlund/racket/tree/generics-from-scratch
 
  (The from scratch just refers to the process of rebuilding the git
  history, I didn't go out of my way to rewrite anything in the code base
  from
  scratch, although in some places a lot of code did move around.)
 
  What's new in the branch:
 
  - Generics now support a few new options
- #:fallbacks specifies fallback method implementations for instances
  with
  no implementation
- #:fast-defaults specifies instances on a fast path, useful for
  built-in types
- #:defined-predicate gives a more intuitive and efficient interface
  than
  #:defined-table
- #:derive-property allows generics to piggy-back on existing struct
  properties
 
  - Sets are now a generic datatype through gen:set
- lists are now sets
- the built-in set types are now documented as hash sets
- there are mutable and weak hash sets
- you can define new set types quickly with define-custom-set-types
- most set operations are now methods with fallbacks
- sets now support -copy and -clear operations, plus mutating [!]
  versions
  of operations
 
  - Dictionaries have a few changes
- new macro define-custom-hash-types [*]
- most dict operations are now methods with fallbacks
- dicts now support -copy, -clear, -clear!, and -empty? operations
 
  I've run some benchmarks and performance of the various generic
  operations
  are comparable to the current HEAD, so there should be no major
  performance
  changes with this patch.
 
  [*] I've added define-custom-hash-types and define-custom-set-types
  rather
  than just adding make-custom-set akin to make-custom-hash because
  make-custom-hash is hard to use.  The documented behavior -- that any
  custom
  hash is equal to any other created with the same bindings and
  predicates /
  hash functions -- was never true and can be expensive or at least
  tricky to
  implement.  It seemed more sensible to just remove the erroneous
  documentation on make-custom-hash, and add the definition form to
  create
  constructors for new, explicitly-compatible dict and set types.  Both
  definition forms bind predicates and constructors for new (set or dict)
  types with immutable, mutable, and weak variants that inter-operate

Re: [racket-dev] Generics updates

2013-10-02 Thread Robby Findler
That sounds right.

But just in case there is any confusion on the larger point: predicates as
way we check properties to ensure good properties of our abstractions is
one of the important things that we have mostly gotten right in Racket.
Chaperones, separate pair? and mpair? predicates, and presumably lots of
other stuff are the way they are for this kind of reason.

Robby


On Wed, Oct 2, 2013 at 3:21 PM, Jay McCarthy jay.mccar...@gmail.com wrote:

 Even if we were to remove set-add! from gen:set and not great gen:mset
 then that would not be a vaild property. Generics are a lower bound on
 the interface, not an upper bound, so there could be other functions
 on the data structure that implement mutation. For instance, a gen:set
 could be made for an external resource that was set-like.

 I think what you want is something like gen:fset that has no methods,
 but is used for set authors to tag their set as having this property
 for the benefit of consumers (which cannot be enforced.) Your library
 would then consume fsets and not sets.

 Jay


 On Wed, Oct 2, 2013 at 2:09 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
  If we do go this way, we should be careful about the subtyping
 relationship
  since we want a predicate that means will not be mutated and I can rely
 on
  that to reason about my library's behavior and if mutable sets are a
  sub-thing of immutable ones, we might lose that (depending on how things
 are
  set up).
 
  Robby
 
 
  On Wed, Oct 2, 2013 at 2:57 PM, Jay McCarthy jay.mccar...@gmail.com
 wrote:
 
  No. Mutable sets would implement gen:set and then just have a few more
  methods in the gen:mset interface. Structs can implement any number of
  generics.
 
  Jay
 
  On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu
 wrote:
   This means I can't interchange between mutable and immutable sets for
 my
   functions that only need to read generic sets, unless we further
 subdivide
   and have gen:set-query gen:set-constructor gen:set-mconstruct.
  
   -Ian
   - Original Message -
   From: Jay McCarthy jay.mccar...@gmail.com
   To: Carl Eastlund c...@ccs.neu.edu
   Cc: Racket Developers dev@racket-lang.org
   Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada
 Eastern
   Subject: Re: [racket-dev] Generics updates
  
   Regarding a point from RacketCon, I don't like that gen:set includes
   functions like set-add! and set-remove!. I think that sets with
   mutations are subclass of get:set and we should have a separate
   gen:mset (or something) interface for mutable versions.
  
   I dislike that an obvious implementation of sets, hash tables, are not
   sets to gen:set, because there are operations that cannot be performed
   on them.
  
   I think that X implements generic G should imply All functions of G
   work on X. But this is not the case with gen:set and hasheq sets, for
   instance.
  
   Jay
  
  
   On Tue, Jul 23, 2013 at 9:37 AM, Carl Eastlund c...@ccs.neu.edu
 wrote:
   My work on adding gen:set, and related changes to define-generics and
   gen:dict, is ready for review and (hopefully) to push to the master
   branch.
   The branch moved in the process of cleaning things up, it's now at:
  
 https://github.com/carl-eastlund/racket/tree/generics-from-scratch
  
   (The from scratch just refers to the process of rebuilding the git
   history, I didn't go out of my way to rewrite anything in the code
 base
   from
   scratch, although in some places a lot of code did move around.)
  
   What's new in the branch:
  
   - Generics now support a few new options
 - #:fallbacks specifies fallback method implementations for
 instances
   with
   no implementation
 - #:fast-defaults specifies instances on a fast path, useful for
   built-in types
 - #:defined-predicate gives a more intuitive and efficient
 interface
   than
   #:defined-table
 - #:derive-property allows generics to piggy-back on existing
 struct
   properties
  
   - Sets are now a generic datatype through gen:set
 - lists are now sets
 - the built-in set types are now documented as hash sets
 - there are mutable and weak hash sets
 - you can define new set types quickly with define-custom-set-types
 - most set operations are now methods with fallbacks
 - sets now support -copy and -clear operations, plus mutating [!]
   versions
   of operations
  
   - Dictionaries have a few changes
 - new macro define-custom-hash-types [*]
 - most dict operations are now methods with fallbacks
 - dicts now support -copy, -clear, -clear!, and -empty? operations
  
   I've run some benchmarks and performance of the various generic
   operations
   are comparable to the current HEAD, so there should be no major
   performance
   changes with this patch.
  
   [*] I've added define-custom-hash-types and define-custom-set-types
   rather
   than just adding make-custom-set akin to make-custom-hash because
   make-custom-hash is hard

Re: [racket-dev] Generics updates

2013-10-02 Thread Jay McCarthy
I agree. I think the important thing with generics is unlike mpair?
the set? predicate only necessarily implies that the methods are
available (which is the source of my original complaint). We need to
design the meaning of predicates just like we design the interface. I
think that if we want mset to be a set then set? cannot imply
immutable? but since that is a valuable property, it is worth
designing a predicate that gives it, if only as a human thing.

Jay

On Wed, Oct 2, 2013 at 2:29 PM, Robby Findler
ro...@eecs.northwestern.edu wrote:
 That sounds right.

 But just in case there is any confusion on the larger point: predicates as
 way we check properties to ensure good properties of our abstractions is one
 of the important things that we have mostly gotten right in Racket.
 Chaperones, separate pair? and mpair? predicates, and presumably lots of
 other stuff are the way they are for this kind of reason.

 Robby


 On Wed, Oct 2, 2013 at 3:21 PM, Jay McCarthy jay.mccar...@gmail.com wrote:

 Even if we were to remove set-add! from gen:set and not great gen:mset
 then that would not be a vaild property. Generics are a lower bound on
 the interface, not an upper bound, so there could be other functions
 on the data structure that implement mutation. For instance, a gen:set
 could be made for an external resource that was set-like.

 I think what you want is something like gen:fset that has no methods,
 but is used for set authors to tag their set as having this property
 for the benefit of consumers (which cannot be enforced.) Your library
 would then consume fsets and not sets.

 Jay


 On Wed, Oct 2, 2013 at 2:09 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
  If we do go this way, we should be careful about the subtyping
  relationship
  since we want a predicate that means will not be mutated and I can rely
  on
  that to reason about my library's behavior and if mutable sets are a
  sub-thing of immutable ones, we might lose that (depending on how things
  are
  set up).
 
  Robby
 
 
  On Wed, Oct 2, 2013 at 2:57 PM, Jay McCarthy jay.mccar...@gmail.com
  wrote:
 
  No. Mutable sets would implement gen:set and then just have a few more
  methods in the gen:mset interface. Structs can implement any number of
  generics.
 
  Jay
 
  On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu
  wrote:
   This means I can't interchange between mutable and immutable sets for
   my
   functions that only need to read generic sets, unless we further
   subdivide
   and have gen:set-query gen:set-constructor gen:set-mconstruct.
  
   -Ian
   - Original Message -
   From: Jay McCarthy jay.mccar...@gmail.com
   To: Carl Eastlund c...@ccs.neu.edu
   Cc: Racket Developers dev@racket-lang.org
   Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada
   Eastern
   Subject: Re: [racket-dev] Generics updates
  
   Regarding a point from RacketCon, I don't like that gen:set includes
   functions like set-add! and set-remove!. I think that sets with
   mutations are subclass of get:set and we should have a separate
   gen:mset (or something) interface for mutable versions.
  
   I dislike that an obvious implementation of sets, hash tables, are
   not
   sets to gen:set, because there are operations that cannot be
   performed
   on them.
  
   I think that X implements generic G should imply All functions of
   G
   work on X. But this is not the case with gen:set and hasheq sets,
   for
   instance.
  
   Jay
  
  
   On Tue, Jul 23, 2013 at 9:37 AM, Carl Eastlund c...@ccs.neu.edu
   wrote:
   My work on adding gen:set, and related changes to define-generics
   and
   gen:dict, is ready for review and (hopefully) to push to the master
   branch.
   The branch moved in the process of cleaning things up, it's now at:
  
 https://github.com/carl-eastlund/racket/tree/generics-from-scratch
  
   (The from scratch just refers to the process of rebuilding the git
   history, I didn't go out of my way to rewrite anything in the code
   base
   from
   scratch, although in some places a lot of code did move around.)
  
   What's new in the branch:
  
   - Generics now support a few new options
 - #:fallbacks specifies fallback method implementations for
   instances
   with
   no implementation
 - #:fast-defaults specifies instances on a fast path, useful for
   built-in types
 - #:defined-predicate gives a more intuitive and efficient
   interface
   than
   #:defined-table
 - #:derive-property allows generics to piggy-back on existing
   struct
   properties
  
   - Sets are now a generic datatype through gen:set
 - lists are now sets
 - the built-in set types are now documented as hash sets
 - there are mutable and weak hash sets
 - you can define new set types quickly with
   define-custom-set-types
 - most set operations are now methods with fallbacks
 - sets now support -copy and -clear operations, plus mutating [!]
   versions
   of operations

Re: [racket-dev] Generics updates

2013-10-02 Thread Sam Tobin-Hochstadt
On Wed, Oct 2, 2013 at 4:29 PM, Robby Findler
ro...@eecs.northwestern.edu wrote:
 That sounds right.

 But just in case there is any confusion on the larger point: predicates as
 way we check properties to ensure good properties of our abstractions is one
 of the important things that we have mostly gotten right in Racket.
 Chaperones, separate pair? and mpair? predicates, and presumably lots of
 other stuff are the way they are for this kind of reason.

Unfortunately, this is only half-true, I think.  In particular, a very
large number of our data structures violate this rule: vectors,
strings, byte strings boxes, hash tables, dictionaries, sequences, and
so on, all provide the same operations on both mutable and immutable
variants.  This is also true in general of structs -- a substruct can
be mutable when the superstruct is immutable.

Ultimately, for the purpose of consistency, I think we should try to
decide what the 'Rackety' style for this is.  Should we follow the
lead of hash tables, where `immutable?` is needed to determine
anything?  Or should we follow the lead of pairs, where there's a
whole separate type?  And how should this interact with subtyping, as
in this discussion?

Personally, I think I prefer separate unrelated data structures, with
a generic interface [1].  Maybe this means we should make `immutable?`
into a generic.

[1] I think that part of the reason some of these are conflated is
lack of generic operations.

Sam


 Robby


 On Wed, Oct 2, 2013 at 3:21 PM, Jay McCarthy jay.mccar...@gmail.com wrote:

 Even if we were to remove set-add! from gen:set and not great gen:mset
 then that would not be a vaild property. Generics are a lower bound on
 the interface, not an upper bound, so there could be other functions
 on the data structure that implement mutation. For instance, a gen:set
 could be made for an external resource that was set-like.

 I think what you want is something like gen:fset that has no methods,
 but is used for set authors to tag their set as having this property
 for the benefit of consumers (which cannot be enforced.) Your library
 would then consume fsets and not sets.

 Jay


 On Wed, Oct 2, 2013 at 2:09 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
  If we do go this way, we should be careful about the subtyping
  relationship
  since we want a predicate that means will not be mutated and I can rely
  on
  that to reason about my library's behavior and if mutable sets are a
  sub-thing of immutable ones, we might lose that (depending on how things
  are
  set up).
 
  Robby
 
 
  On Wed, Oct 2, 2013 at 2:57 PM, Jay McCarthy jay.mccar...@gmail.com
  wrote:
 
  No. Mutable sets would implement gen:set and then just have a few more
  methods in the gen:mset interface. Structs can implement any number of
  generics.
 
  Jay
 
  On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu
  wrote:
   This means I can't interchange between mutable and immutable sets for
   my
   functions that only need to read generic sets, unless we further
   subdivide
   and have gen:set-query gen:set-constructor gen:set-mconstruct.
  
   -Ian
   - Original Message -
   From: Jay McCarthy jay.mccar...@gmail.com
   To: Carl Eastlund c...@ccs.neu.edu
   Cc: Racket Developers dev@racket-lang.org
   Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada
   Eastern
   Subject: Re: [racket-dev] Generics updates
  
   Regarding a point from RacketCon, I don't like that gen:set includes
   functions like set-add! and set-remove!. I think that sets with
   mutations are subclass of get:set and we should have a separate
   gen:mset (or something) interface for mutable versions.
  
   I dislike that an obvious implementation of sets, hash tables, are
   not
   sets to gen:set, because there are operations that cannot be
   performed
   on them.
  
   I think that X implements generic G should imply All functions of
   G
   work on X. But this is not the case with gen:set and hasheq sets,
   for
   instance.
  
   Jay
  
  
   On Tue, Jul 23, 2013 at 9:37 AM, Carl Eastlund c...@ccs.neu.edu
   wrote:
   My work on adding gen:set, and related changes to define-generics
   and
   gen:dict, is ready for review and (hopefully) to push to the master
   branch.
   The branch moved in the process of cleaning things up, it's now at:
  
 https://github.com/carl-eastlund/racket/tree/generics-from-scratch
  
   (The from scratch just refers to the process of rebuilding the git
   history, I didn't go out of my way to rewrite anything in the code
   base
   from
   scratch, although in some places a lot of code did move around.)
  
   What's new in the branch:
  
   - Generics now support a few new options
 - #:fallbacks specifies fallback method implementations for
   instances
   with
   no implementation
 - #:fast-defaults specifies instances on a fast path, useful for
   built-in types
 - #:defined-predicate gives a more intuitive and efficient

Re: [racket-dev] Generics updates

2013-10-02 Thread Jay McCarthy
This is a good message, but I have one quibble.

I think it makes sense to separate data immutability and logical
immutability. For instance, I may have a library for querying REST
services where a server object is represented by an immutable
string. The string is immutable? but the service behind it is not. I
don't want the happenstance of which data was used to construct the
object to give the wrong idea of its mutability.

Jay

On Wed, Oct 2, 2013 at 2:41 PM, Sam Tobin-Hochstadt
sa...@cs.indiana.edu wrote:
 On Wed, Oct 2, 2013 at 4:29 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
 That sounds right.

 But just in case there is any confusion on the larger point: predicates as
 way we check properties to ensure good properties of our abstractions is one
 of the important things that we have mostly gotten right in Racket.
 Chaperones, separate pair? and mpair? predicates, and presumably lots of
 other stuff are the way they are for this kind of reason.

 Unfortunately, this is only half-true, I think.  In particular, a very
 large number of our data structures violate this rule: vectors,
 strings, byte strings boxes, hash tables, dictionaries, sequences, and
 so on, all provide the same operations on both mutable and immutable
 variants.  This is also true in general of structs -- a substruct can
 be mutable when the superstruct is immutable.

 Ultimately, for the purpose of consistency, I think we should try to
 decide what the 'Rackety' style for this is.  Should we follow the
 lead of hash tables, where `immutable?` is needed to determine
 anything?  Or should we follow the lead of pairs, where there's a
 whole separate type?  And how should this interact with subtyping, as
 in this discussion?

 Personally, I think I prefer separate unrelated data structures, with
 a generic interface [1].  Maybe this means we should make `immutable?`
 into a generic.

 [1] I think that part of the reason some of these are conflated is
 lack of generic operations.

 Sam


 Robby


 On Wed, Oct 2, 2013 at 3:21 PM, Jay McCarthy jay.mccar...@gmail.com wrote:

 Even if we were to remove set-add! from gen:set and not great gen:mset
 then that would not be a vaild property. Generics are a lower bound on
 the interface, not an upper bound, so there could be other functions
 on the data structure that implement mutation. For instance, a gen:set
 could be made for an external resource that was set-like.

 I think what you want is something like gen:fset that has no methods,
 but is used for set authors to tag their set as having this property
 for the benefit of consumers (which cannot be enforced.) Your library
 would then consume fsets and not sets.

 Jay


 On Wed, Oct 2, 2013 at 2:09 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
  If we do go this way, we should be careful about the subtyping
  relationship
  since we want a predicate that means will not be mutated and I can rely
  on
  that to reason about my library's behavior and if mutable sets are a
  sub-thing of immutable ones, we might lose that (depending on how things
  are
  set up).
 
  Robby
 
 
  On Wed, Oct 2, 2013 at 2:57 PM, Jay McCarthy jay.mccar...@gmail.com
  wrote:
 
  No. Mutable sets would implement gen:set and then just have a few more
  methods in the gen:mset interface. Structs can implement any number of
  generics.
 
  Jay
 
  On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu
  wrote:
   This means I can't interchange between mutable and immutable sets for
   my
   functions that only need to read generic sets, unless we further
   subdivide
   and have gen:set-query gen:set-constructor gen:set-mconstruct.
  
   -Ian
   - Original Message -
   From: Jay McCarthy jay.mccar...@gmail.com
   To: Carl Eastlund c...@ccs.neu.edu
   Cc: Racket Developers dev@racket-lang.org
   Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada
   Eastern
   Subject: Re: [racket-dev] Generics updates
  
   Regarding a point from RacketCon, I don't like that gen:set includes
   functions like set-add! and set-remove!. I think that sets with
   mutations are subclass of get:set and we should have a separate
   gen:mset (or something) interface for mutable versions.
  
   I dislike that an obvious implementation of sets, hash tables, are
   not
   sets to gen:set, because there are operations that cannot be
   performed
   on them.
  
   I think that X implements generic G should imply All functions of
   G
   work on X. But this is not the case with gen:set and hasheq sets,
   for
   instance.
  
   Jay
  
  
   On Tue, Jul 23, 2013 at 9:37 AM, Carl Eastlund c...@ccs.neu.edu
   wrote:
   My work on adding gen:set, and related changes to define-generics
   and
   gen:dict, is ready for review and (hopefully) to push to the master
   branch.
   The branch moved in the process of cleaning things up, it's now at:
  
 https://github.com/carl-eastlund/racket/tree/generics-from-scratch
  
   (The from scratch just refers

Re: [racket-dev] Generics updates

2013-10-02 Thread Carl Eastlund
Short(ish) answer until I get reliable internet in my new apartment --
gen:set is modeled after gen:dict.  I don't want us to have a new design
for each interface.  Because methods are optional, we get by with one name
for one or more related subinterfaces.  That's the principle by which I
justified set-add and set-add! In one interface.

And if we separate them, we need one interface with just queries, then four
more for add, remove, add!, and remove!, at the very least.  It's a messy
direction to go in.

Carl Eastlund

--
WARNING!  Poorly-typed cell phone email precedes.
On Oct 2, 2013 4:35 PM, Jay McCarthy jay.mccar...@gmail.com wrote:

 I agree. I think the important thing with generics is unlike mpair?
 the set? predicate only necessarily implies that the methods are
 available (which is the source of my original complaint). We need to
 design the meaning of predicates just like we design the interface. I
 think that if we want mset to be a set then set? cannot imply
 immutable? but since that is a valuable property, it is worth
 designing a predicate that gives it, if only as a human thing.

 Jay

 On Wed, Oct 2, 2013 at 2:29 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
  That sounds right.
 
  But just in case there is any confusion on the larger point: predicates
 as
  way we check properties to ensure good properties of our abstractions is
 one
  of the important things that we have mostly gotten right in Racket.
  Chaperones, separate pair? and mpair? predicates, and presumably lots of
  other stuff are the way they are for this kind of reason.
 
  Robby
 
 
  On Wed, Oct 2, 2013 at 3:21 PM, Jay McCarthy jay.mccar...@gmail.com
 wrote:
 
  Even if we were to remove set-add! from gen:set and not great gen:mset
  then that would not be a vaild property. Generics are a lower bound on
  the interface, not an upper bound, so there could be other functions
  on the data structure that implement mutation. For instance, a gen:set
  could be made for an external resource that was set-like.
 
  I think what you want is something like gen:fset that has no methods,
  but is used for set authors to tag their set as having this property
  for the benefit of consumers (which cannot be enforced.) Your library
  would then consume fsets and not sets.
 
  Jay
 
 
  On Wed, Oct 2, 2013 at 2:09 PM, Robby Findler
  ro...@eecs.northwestern.edu wrote:
   If we do go this way, we should be careful about the subtyping
   relationship
   since we want a predicate that means will not be mutated and I can
 rely
   on
   that to reason about my library's behavior and if mutable sets are a
   sub-thing of immutable ones, we might lose that (depending on how
 things
   are
   set up).
  
   Robby
  
  
   On Wed, Oct 2, 2013 at 2:57 PM, Jay McCarthy jay.mccar...@gmail.com
   wrote:
  
   No. Mutable sets would implement gen:set and then just have a few
 more
   methods in the gen:mset interface. Structs can implement any number
 of
   generics.
  
   Jay
  
   On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu
   wrote:
This means I can't interchange between mutable and immutable sets
 for
my
functions that only need to read generic sets, unless we further
subdivide
and have gen:set-query gen:set-constructor gen:set-mconstruct.
   
-Ian
- Original Message -
From: Jay McCarthy jay.mccar...@gmail.com
To: Carl Eastlund c...@ccs.neu.edu
Cc: Racket Developers dev@racket-lang.org
Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada
Eastern
Subject: Re: [racket-dev] Generics updates
   
Regarding a point from RacketCon, I don't like that gen:set
 includes
functions like set-add! and set-remove!. I think that sets with
mutations are subclass of get:set and we should have a separate
gen:mset (or something) interface for mutable versions.
   
I dislike that an obvious implementation of sets, hash tables, are
not
sets to gen:set, because there are operations that cannot be
performed
on them.
   
I think that X implements generic G should imply All functions
 of
G
work on X. But this is not the case with gen:set and hasheq sets,
for
instance.
   
Jay
   
   
On Tue, Jul 23, 2013 at 9:37 AM, Carl Eastlund c...@ccs.neu.edu
wrote:
My work on adding gen:set, and related changes to define-generics
and
gen:dict, is ready for review and (hopefully) to push to the
 master
branch.
The branch moved in the process of cleaning things up, it's now
 at:
   
   
 https://github.com/carl-eastlund/racket/tree/generics-from-scratch
   
(The from scratch just refers to the process of rebuilding the
 git
history, I didn't go out of my way to rewrite anything in the code
base
from
scratch, although in some places a lot of code did move around.)
   
What's new in the branch:
   
- Generics now support a few new options
  - #:fallbacks specifies

Re: [racket-dev] Generics updates

2013-10-02 Thread Sam Tobin-Hochstadt
On Wed, Oct 2, 2013 at 4:44 PM, Jay McCarthy jay.mccar...@gmail.com wrote:
 This is a good message, but I have one quibble.

 I think it makes sense to separate data immutability and logical
 immutability. For instance, I may have a library for querying REST
 services where a server object is represented by an immutable
 string. The string is immutable? but the service behind it is not. I
 don't want the happenstance of which data was used to construct the
 object to give the wrong idea of its mutability.

I think what you're saying here is that part of what we want from
immutability is knowing that doing the same thing again on the
immutable data won't change the behavior.  But of course, this is a
property of _both_ the data and the operation -- `file-bytes` takes
immutable input, but running it multiple times doesn't guarantee
anything. I'm not sure where this leaves us in terms of API design,
though.  In a capability-based language, or in a language like Clean,
`file-bytes` might take the filesystem as input, but that's not very
Rackety. :)

My inclination is that a dictionary implemented with immutable data
structures but representing the results of `getenv` shouldn't be
`immutable?`, whereas maybe one with mutable insides but a functional
interface should be, but that really depends on what we're trying to
say.

Sam


 Jay

 On Wed, Oct 2, 2013 at 2:41 PM, Sam Tobin-Hochstadt
 sa...@cs.indiana.edu wrote:
 On Wed, Oct 2, 2013 at 4:29 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
 That sounds right.

 But just in case there is any confusion on the larger point: predicates as
 way we check properties to ensure good properties of our abstractions is one
 of the important things that we have mostly gotten right in Racket.
 Chaperones, separate pair? and mpair? predicates, and presumably lots of
 other stuff are the way they are for this kind of reason.

 Unfortunately, this is only half-true, I think.  In particular, a very
 large number of our data structures violate this rule: vectors,
 strings, byte strings boxes, hash tables, dictionaries, sequences, and
 so on, all provide the same operations on both mutable and immutable
 variants.  This is also true in general of structs -- a substruct can
 be mutable when the superstruct is immutable.

 Ultimately, for the purpose of consistency, I think we should try to
 decide what the 'Rackety' style for this is.  Should we follow the
 lead of hash tables, where `immutable?` is needed to determine
 anything?  Or should we follow the lead of pairs, where there's a
 whole separate type?  And how should this interact with subtyping, as
 in this discussion?

 Personally, I think I prefer separate unrelated data structures, with
 a generic interface [1].  Maybe this means we should make `immutable?`
 into a generic.

 [1] I think that part of the reason some of these are conflated is
 lack of generic operations.

 Sam


 Robby


 On Wed, Oct 2, 2013 at 3:21 PM, Jay McCarthy jay.mccar...@gmail.com wrote:

 Even if we were to remove set-add! from gen:set and not great gen:mset
 then that would not be a vaild property. Generics are a lower bound on
 the interface, not an upper bound, so there could be other functions
 on the data structure that implement mutation. For instance, a gen:set
 could be made for an external resource that was set-like.

 I think what you want is something like gen:fset that has no methods,
 but is used for set authors to tag their set as having this property
 for the benefit of consumers (which cannot be enforced.) Your library
 would then consume fsets and not sets.

 Jay


 On Wed, Oct 2, 2013 at 2:09 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
  If we do go this way, we should be careful about the subtyping
  relationship
  since we want a predicate that means will not be mutated and I can rely
  on
  that to reason about my library's behavior and if mutable sets are a
  sub-thing of immutable ones, we might lose that (depending on how things
  are
  set up).
 
  Robby
 
 
  On Wed, Oct 2, 2013 at 2:57 PM, Jay McCarthy jay.mccar...@gmail.com
  wrote:
 
  No. Mutable sets would implement gen:set and then just have a few more
  methods in the gen:mset interface. Structs can implement any number of
  generics.
 
  Jay
 
  On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu
  wrote:
   This means I can't interchange between mutable and immutable sets for
   my
   functions that only need to read generic sets, unless we further
   subdivide
   and have gen:set-query gen:set-constructor gen:set-mconstruct.
  
   -Ian
   - Original Message -
   From: Jay McCarthy jay.mccar...@gmail.com
   To: Carl Eastlund c...@ccs.neu.edu
   Cc: Racket Developers dev@racket-lang.org
   Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada
   Eastern
   Subject: Re: [racket-dev] Generics updates
  
   Regarding a point from RacketCon, I don't like that gen:set includes
   functions like set-add! and set-remove!. I

Re: [racket-dev] Generics updates

2013-10-02 Thread Jay McCarthy
Totally agree.

On Wed, Oct 2, 2013 at 2:53 PM, Sam Tobin-Hochstadt
sa...@cs.indiana.edu wrote:
 On Wed, Oct 2, 2013 at 4:44 PM, Jay McCarthy jay.mccar...@gmail.com wrote:
 This is a good message, but I have one quibble.

 I think it makes sense to separate data immutability and logical
 immutability. For instance, I may have a library for querying REST
 services where a server object is represented by an immutable
 string. The string is immutable? but the service behind it is not. I
 don't want the happenstance of which data was used to construct the
 object to give the wrong idea of its mutability.

 I think what you're saying here is that part of what we want from
 immutability is knowing that doing the same thing again on the
 immutable data won't change the behavior.  But of course, this is a
 property of _both_ the data and the operation -- `file-bytes` takes
 immutable input, but running it multiple times doesn't guarantee
 anything. I'm not sure where this leaves us in terms of API design,
 though.  In a capability-based language, or in a language like Clean,
 `file-bytes` might take the filesystem as input, but that's not very
 Rackety. :)

 My inclination is that a dictionary implemented with immutable data
 structures but representing the results of `getenv` shouldn't be
 `immutable?`, whereas maybe one with mutable insides but a functional
 interface should be, but that really depends on what we're trying to
 say.

 Sam


 Jay

 On Wed, Oct 2, 2013 at 2:41 PM, Sam Tobin-Hochstadt
 sa...@cs.indiana.edu wrote:
 On Wed, Oct 2, 2013 at 4:29 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
 That sounds right.

 But just in case there is any confusion on the larger point: predicates as
 way we check properties to ensure good properties of our abstractions is 
 one
 of the important things that we have mostly gotten right in Racket.
 Chaperones, separate pair? and mpair? predicates, and presumably lots of
 other stuff are the way they are for this kind of reason.

 Unfortunately, this is only half-true, I think.  In particular, a very
 large number of our data structures violate this rule: vectors,
 strings, byte strings boxes, hash tables, dictionaries, sequences, and
 so on, all provide the same operations on both mutable and immutable
 variants.  This is also true in general of structs -- a substruct can
 be mutable when the superstruct is immutable.

 Ultimately, for the purpose of consistency, I think we should try to
 decide what the 'Rackety' style for this is.  Should we follow the
 lead of hash tables, where `immutable?` is needed to determine
 anything?  Or should we follow the lead of pairs, where there's a
 whole separate type?  And how should this interact with subtyping, as
 in this discussion?

 Personally, I think I prefer separate unrelated data structures, with
 a generic interface [1].  Maybe this means we should make `immutable?`
 into a generic.

 [1] I think that part of the reason some of these are conflated is
 lack of generic operations.

 Sam


 Robby


 On Wed, Oct 2, 2013 at 3:21 PM, Jay McCarthy jay.mccar...@gmail.com 
 wrote:

 Even if we were to remove set-add! from gen:set and not great gen:mset
 then that would not be a vaild property. Generics are a lower bound on
 the interface, not an upper bound, so there could be other functions
 on the data structure that implement mutation. For instance, a gen:set
 could be made for an external resource that was set-like.

 I think what you want is something like gen:fset that has no methods,
 but is used for set authors to tag their set as having this property
 for the benefit of consumers (which cannot be enforced.) Your library
 would then consume fsets and not sets.

 Jay


 On Wed, Oct 2, 2013 at 2:09 PM, Robby Findler
 ro...@eecs.northwestern.edu wrote:
  If we do go this way, we should be careful about the subtyping
  relationship
  since we want a predicate that means will not be mutated and I can rely
  on
  that to reason about my library's behavior and if mutable sets are a
  sub-thing of immutable ones, we might lose that (depending on how things
  are
  set up).
 
  Robby
 
 
  On Wed, Oct 2, 2013 at 2:57 PM, Jay McCarthy jay.mccar...@gmail.com
  wrote:
 
  No. Mutable sets would implement gen:set and then just have a few more
  methods in the gen:mset interface. Structs can implement any number of
  generics.
 
  Jay
 
  On Wed, Oct 2, 2013 at 1:31 PM, J. Ian Johnson i...@ccs.neu.edu
  wrote:
   This means I can't interchange between mutable and immutable sets for
   my
   functions that only need to read generic sets, unless we further
   subdivide
   and have gen:set-query gen:set-constructor gen:set-mconstruct.
  
   -Ian
   - Original Message -
   From: Jay McCarthy jay.mccar...@gmail.com
   To: Carl Eastlund c...@ccs.neu.edu
   Cc: Racket Developers dev@racket-lang.org
   Sent: Wednesday, October 2, 2013 3:23:07 PM GMT -05:00 US/Canada
   Eastern
   Subject: Re: [racket-dev] Generics updates

Re: [racket-dev] Generics updates

2013-08-03 Thread Vincent St-Amour
At Fri, 2 Aug 2013 15:33:02 -0400,
Carl Eastlund wrote:
 
 [1  text/plain; UTF-8 (7bit)]
 On Fri, Aug 2, 2013 at 1:47 PM, Stephen Chang stch...@ccs.neu.edu wrote:
 
   With that in mind, I think it would make sense to move `set-first' and
   `set-empty?' to the primitive set (making it clear that they are
   optional, and can be derived from `set-stream' if need be). With those
   two in the primitive set, anything that implements all the primitives
   should get all the derived for free, right?
 
  Oh yeah, I like that better than moving set-stream to primitives
  since they are more standard set operations.
 
 
 So the proposal for primitive methods is to pick one canonical set of
 methods from which all the others can be derived?  I'm fairly sure there's
 more than one such set, and I'm not sure there's one choice that's clearly
 better than the others.

 I can understand the benefits of documenting a
 suggested set, but given that it is an arbitrary and pragmatic
 distinction, I'm not sure I'd want to set them off in a section any more.
 I'd just make a list in the gen:set description or something.

Sounds good to me. As long as there's a clear easy starting point for
someone implementing a new set type, I think we're good.

Vincent
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-02 Thread Matthias Felleisen

This whole discussion reminds me of the idea of specialization interface 
specification. The notion is due to Lamping, I think. Stevie and I read the 
paper and his class contracts provide some of the power of SIs but not all. In 
particular, they fail to provide the power that seems to be necessary here: 

 specifying the cycles among methods that is required to be overridden 
wholesale 
 
 specifying the 'what I get for free' methods 

As far as I know, there is no PL that actually supports such specs and everyone 
relies on plain old English docs to get this across. Then everyone gets it 
wrong the first time and plays until it works. 

It's quite likely to be a DLS-level research paper, possibly OOPSLA if we 
integrate it with a type system eventually. -- Matthias





On Aug 1, 2013, at 7:30 PM, Carl Eastlund wrote:

 No, that doesn't work.  If someone implements, say, an efficient subset? 
 test, then set=? should use that rather than iterating using set-stream and 
 set-member?.  You should use the highest-level methods you can, in order to 
 get the most out of an implementation.  Which is why I made all the fallback 
 implementations I did, to give implementers the best flexibility possible for 
 getting a good implementation of all methods for the minimum possible effort 
 on their part.
 
 Similarly, I don't want to make set-stream primitive, because if someone 
 does implement set-first and set-rest, it should be derivable.
 
 Carl Eastlund
 
 
 On Thu, Aug 1, 2013 at 7:26 PM, Stephen Chang stch...@ccs.neu.edu wrote:
  Would it be better to just remove the primitve / derived distinction,
  since it's somewhat artificial, and leave it up to the individual method
  descriptions?  Is there some better way I should be describing things?
 
 Ok I can see now that there's no easy way to organize the methods.
 
 I think we should keep some distinction, since as a programmer it's
 good to know exactly what methods I have to implement. However, to me
 fallback implies that I should get it for free, so it seems most
 intuitive if derived methods only depend on primitive methods. Then
 for some subset of primitive methods that I implement, I should get
 the derived methods that depend on those primitives. I'll have to
 think more about what should be derived and primitive, but for now I
 think the easiest thing is to edit the docs to move set-stream (or
 some equivalent) into the primitive list?
 
 
 
 
  Carl Eastlund
 
 
  On Thu, Aug 1, 2013 at 6:51 PM, Stephen Chang stch...@ccs.neu.edu wrote:
 
   For the other part, I either should have made it as you say -- implement
   the  primitive ones and you get the others -- or else I should have
   clearly
   documented the relationship somewhere.
 
  You did document the dependencies, but some of them are circular, ie
  some derived rely on other derived. I'd definitely be happy to patch
  things myself, but I guess I dont have a concrete complaint yet :),
  only that the distinctions feel somewhat arbitrary and did not match
  my initial intuition, which is why I'm looking for additional insight.
 
 
   Do you have examples of which ones don't come for free with the
   primitive
   methods?
 
  Very few of the derived come free because most rely on set-stream,
  but set-stream is not primitive which is why I thought there might
  be a distinction between iterable sets and non-iterable.
 
 
 
 
  
   Carl Eastlund
  
  
   On Thu, Aug 1, 2013 at 6:27 PM, Stephen Chang stch...@ccs.neu.edu
   wrote:
  
   Just played a bit with gen:set. It looks great and in particular the
   fallback implementations are very convenient.
  
   One comment: the distinction between primitive methods and derived
   methods confused me somewhat. Can you explain the reasoning for
   determining which is which?
  
   For example, when I first read the docs, I thought that if I
   implemented the primitives, I would get the derived, but that's not
   the case since some of the derived methods depend on each other.
   Reading the docs more thoroughly, it sort of seems like there's an
   implicit separation along the lines of iterability, ie, derived sets
   are iterable since many of the derived methods require set-stream,
   but that's not exactly right either.
  
  
   On Thu, Jul 25, 2013 at 1:58 PM, Carl Eastlund c...@ccs.neu.edu wrote:
After some fixes, mostly to contracts and documentation, I've pushed
the
new
generics and set features to the master branch.
   
Carl Eastlund
   
   
On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund c...@ccs.neu.edu
wrote:
   
My work on adding gen:set, and related changes to define-generics
and
gen:dict, is ready for review and (hopefully) to push to the master
branch.
The branch moved in the process of cleaning things up, it's now at:
   
  https://github.com/carl-eastlund/racket/tree/generics-from-scratch
   
(The from scratch just refers to the process of rebuilding the git
history, 

Re: [racket-dev] Generics updates

2013-08-02 Thread Vincent St-Amour
At Thu, 1 Aug 2013 18:56:08 -0400,
Carl Eastlund wrote:
 Ah, yes, set-stream isn't primitive because it can be derived if you have
 set-first and either set-rest or set-remove.  And I know there are
 dependency cycles, this is intentional so that you can implement any one of
 several related things, but most of them were supposed to go all the way
 down to primitive methods (in some sense) if all else failed.
 
 Would it be better to just remove the primitve / derived distinction,
 since it's somewhat artificial, and leave it up to the individual method
 descriptions?  Is there some better way I should be describing things?

I like the primitive / derived distinction, but I don't think that the
distinction should be done based on the presence of fallback
implementations. IMO, it makes more sense to interpret it like Stephen
did: what do I need to write to get a minimum viable set type and get
the rest for free. Presence or absence of fallbacks is just an
implementation detail. If we take that view, then basic (or something)
may make more sense than primitive, though.

With that in mind, I think it would make sense to move `set-first' and
`set-empty?' to the primitive set (making it clear that they are
optional, and can be derived from `set-stream' if need be). With those
two in the primitive set, anything that implements all the primitives
should get all the derived for free, right?

Vincent
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-02 Thread Stephen Chang
 With that in mind, I think it would make sense to move `set-first' and
 `set-empty?' to the primitive set (making it clear that they are
 optional, and can be derived from `set-stream' if need be). With those
 two in the primitive set, anything that implements all the primitives
 should get all the derived for free, right?

Oh yeah, I like that better than moving set-stream to primitives
since they are more standard set operations.

Carl, I dont see how guaranteeing some fallback implementations
affects allowing more efficient versions. I think most programmers
understand that the default implementation is probably not very
efficient.







 Vincent
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-02 Thread Carl Eastlund
On Fri, Aug 2, 2013 at 1:47 PM, Stephen Chang stch...@ccs.neu.edu wrote:

  With that in mind, I think it would make sense to move `set-first' and
  `set-empty?' to the primitive set (making it clear that they are
  optional, and can be derived from `set-stream' if need be). With those
  two in the primitive set, anything that implements all the primitives
  should get all the derived for free, right?

 Oh yeah, I like that better than moving set-stream to primitives
 since they are more standard set operations.


So the proposal for primitive methods is to pick one canonical set of
methods from which all the others can be derived?  I'm fairly sure there's
more than one such set, and I'm not sure there's one choice that's clearly
better than the others. I can understand the benefits of documenting a
suggested set, but given that it is an arbitrary and pragmatic
distinction, I'm not sure I'd want to set them off in a section any more.
I'd just make a list in the gen:set description or something.

Carl, I dont see how guaranteeing some fallback implementations
 affects allowing more efficient versions. I think most programmers
 understand that the default implementation is probably not very
 efficient.


Yes, but a default implementation doesn't have to be inefficient.  Right
now the fallback implementation of set=? and proper-subset? will be
efficient if the implementation of subset? is efficient.  Your proposal to
make fallbacks depend only on primitive methods would prevent that.  I
don't understand why we'd want to prevent intelligent fallbacks like I've
made the effort to write, just to draw a line in the sand.

--Carl
_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-02 Thread Stephen Chang
Actually, I am realizing that every derived method depends on
set-stream, even the ones that don't document it (ie set-union,
set-union!, set-intersect, set-intersect!, etc), since they use
in-set.

I was in the process of creating a patch for the docs to add the
missing dependencies but I ran into an issue that I think warrants
discussion.

When the docs specifies dependencies for derived methods, there are
actually two kinds that are being conflated.

*** The first kind of dependency is stricter and requires the
programmer to explicitly implement the required methods, and fallbacks
do not count. In the code, this dependency is enforced with a call to
the #:defined-predicated supplied to define-generics.

Example:

set-copy says it depends on set-clear and set-add!.

Below is a set implementation that implements all the primitive
methods plus set-stream. There exist set-clear and set-add! functions
but set-clear is a fallback so set-copy wont work. Only if I
explicitly implement set-clear will I get set-copy.

(struct lstset (lst)
  #:transparent
  #:methods gen:set
  [(define (set-member? s x) (match s [(lstset lst) (member x lst)]))
   (define (set-add s x)
 (match s
   [(lstset lst)
(lstset (cons x (filter (λ (y) (not (equal? y x))) lst)))]))
   (define (set-remove s x) (match s [(lstset lst) (lstset (remove x lst))]))
   (define (set-add! s x) (void))
   (define (set-remove! s x) (void))
   (define (set-stream s) (lstset-lst s))])

 (set-add (lstset '(1 2)) 4)
(lstset '(4 1 2))
 (set-clear (lstset '(1 2)))
(lstset '())
 (set-copy (lstset '(1 2 3)))
. . set-copy: not implemented for (lstset '(1 2 3))



*** The second kind of dependency is looser and allows fallbacks. For
example set-count requires set-stream, but if I implement in-set,
that is good enough.


I guess my question is, is this a docs issue, or should the code have
more calls to set-implements?



On Fri, Aug 2, 2013 at 1:47 PM, Stephen Chang stch...@ccs.neu.edu wrote:
 With that in mind, I think it would make sense to move `set-first' and
 `set-empty?' to the primitive set (making it clear that they are
 optional, and can be derived from `set-stream' if need be). With those
 two in the primitive set, anything that implements all the primitives
 should get all the derived for free, right?

 Oh yeah, I like that better than moving set-stream to primitives
 since they are more standard set operations.

 Carl, I dont see how guaranteeing some fallback implementations
 affects allowing more efficient versions. I think most programmers
 understand that the default implementation is probably not very
 efficient.







 Vincent

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-02 Thread Carl Eastlund
Yes, this is an issue.  I kind of vaguely hint at it in the documentation,
and didn't get around to making it an explicit point -- I use the phrase
implements for things that have to be directly implemented, and
supports for sort of transitive implements.  I use in-set and things
like it in some of the fallbacks because the dependencies for set-stream
are somewhat complex, and I didn't want to repeat the logic in each and
every case; I wanted to just call set-stream.  At some point I tried to
make an indirect helper that did dependency checking and reported errors in
terms of the primary method being called, but it got a bit cumbersome.  I
probably should have seen through the better code and docs, but I sort of
hit a point of I need to just push this and see how it goes.

So, for documenting this, off the top of my head I'd define tech terms
implemented method and supported method in the documentation for
define-generics, and refer to them as necessary in methods for gen:set and
so on.  That way, saying that, for instance, set-count is a supported
method whenever set-stream is a supported method, allows the documentation
to imply all the direct dependencies of set-stream on things that need to
be implemented methods, without having to restate them all.

For the implementation, what we have would fit the docs, and it might also
be possible to slightly improve the error messages with some refactoring.

Carl Eastlund


On Fri, Aug 2, 2013 at 3:43 PM, Stephen Chang stch...@ccs.neu.edu wrote:

 Actually, I am realizing that every derived method depends on
 set-stream, even the ones that don't document it (ie set-union,
 set-union!, set-intersect, set-intersect!, etc), since they use
 in-set.

 I was in the process of creating a patch for the docs to add the
 missing dependencies but I ran into an issue that I think warrants
 discussion.

 When the docs specifies dependencies for derived methods, there are
 actually two kinds that are being conflated.

 *** The first kind of dependency is stricter and requires the
 programmer to explicitly implement the required methods, and fallbacks
 do not count. In the code, this dependency is enforced with a call to
 the #:defined-predicated supplied to define-generics.

 Example:

 set-copy says it depends on set-clear and set-add!.

 Below is a set implementation that implements all the primitive
 methods plus set-stream. There exist set-clear and set-add! functions
 but set-clear is a fallback so set-copy wont work. Only if I
 explicitly implement set-clear will I get set-copy.

 (struct lstset (lst)
   #:transparent
   #:methods gen:set
   [(define (set-member? s x) (match s [(lstset lst) (member x lst)]))
(define (set-add s x)
  (match s
[(lstset lst)
 (lstset (cons x (filter (λ (y) (not (equal? y x))) lst)))]))
(define (set-remove s x) (match s [(lstset lst) (lstset (remove x
 lst))]))
(define (set-add! s x) (void))
(define (set-remove! s x) (void))
(define (set-stream s) (lstset-lst s))])

  (set-add (lstset '(1 2)) 4)
 (lstset '(4 1 2))
  (set-clear (lstset '(1 2)))
 (lstset '())
  (set-copy (lstset '(1 2 3)))
 . . set-copy: not implemented for (lstset '(1 2 3))



 *** The second kind of dependency is looser and allows fallbacks. For
 example set-count requires set-stream, but if I implement in-set,
 that is good enough.


 I guess my question is, is this a docs issue, or should the code have
 more calls to set-implements?



 On Fri, Aug 2, 2013 at 1:47 PM, Stephen Chang stch...@ccs.neu.edu wrote:
  With that in mind, I think it would make sense to move `set-first' and
  `set-empty?' to the primitive set (making it clear that they are
  optional, and can be derived from `set-stream' if need be). With those
  two in the primitive set, anything that implements all the primitives
  should get all the derived for free, right?
 
  Oh yeah, I like that better than moving set-stream to primitives
  since they are more standard set operations.
 
  Carl, I dont see how guaranteeing some fallback implementations
  affects allowing more efficient versions. I think most programmers
  understand that the default implementation is probably not very
  efficient.
 
 
 
 
 
 
 
  Vincent


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-01 Thread Stephen Chang
Just played a bit with gen:set. It looks great and in particular the
fallback implementations are very convenient.

One comment: the distinction between primitive methods and derived
methods confused me somewhat. Can you explain the reasoning for
determining which is which?

For example, when I first read the docs, I thought that if I
implemented the primitives, I would get the derived, but that's not
the case since some of the derived methods depend on each other.
Reading the docs more thoroughly, it sort of seems like there's an
implicit separation along the lines of iterability, ie, derived sets
are iterable since many of the derived methods require set-stream,
but that's not exactly right either.


On Thu, Jul 25, 2013 at 1:58 PM, Carl Eastlund c...@ccs.neu.edu wrote:
 After some fixes, mostly to contracts and documentation, I've pushed the new
 generics and set features to the master branch.

 Carl Eastlund


 On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund c...@ccs.neu.edu wrote:

 My work on adding gen:set, and related changes to define-generics and
 gen:dict, is ready for review and (hopefully) to push to the master branch.
 The branch moved in the process of cleaning things up, it's now at:

   https://github.com/carl-eastlund/racket/tree/generics-from-scratch

 (The from scratch just refers to the process of rebuilding the git
 history, I didn't go out of my way to rewrite anything in the code base from
 scratch, although in some places a lot of code did move around.)

 What's new in the branch:

 - Generics now support a few new options
   - #:fallbacks specifies fallback method implementations for instances
 with no implementation
   - #:fast-defaults specifies instances on a fast path, useful for
 built-in types
   - #:defined-predicate gives a more intuitive and efficient interface
 than #:defined-table
   - #:derive-property allows generics to piggy-back on existing struct
 properties

 - Sets are now a generic datatype through gen:set
   - lists are now sets
   - the built-in set types are now documented as hash sets
   - there are mutable and weak hash sets
   - you can define new set types quickly with define-custom-set-types
   - most set operations are now methods with fallbacks
   - sets now support -copy and -clear operations, plus mutating [!]
 versions of operations

 - Dictionaries have a few changes
   - new macro define-custom-hash-types [*]
   - most dict operations are now methods with fallbacks
   - dicts now support -copy, -clear, -clear!, and -empty? operations

 I've run some benchmarks and performance of the various generic operations
 are comparable to the current HEAD, so there should be no major performance
 changes with this patch.

 [*] I've added define-custom-hash-types and define-custom-set-types rather
 than just adding make-custom-set akin to make-custom-hash because
 make-custom-hash is hard to use.  The documented behavior -- that any custom
 hash is equal to any other created with the same bindings and predicates /
 hash functions -- was never true and can be expensive or at least tricky to
 implement.  It seemed more sensible to just remove the erroneous
 documentation on make-custom-hash, and add the definition form to create
 constructors for new, explicitly-compatible dict and set types.  Both
 definition forms bind predicates and constructors for new (set or dict)
 types with immutable, mutable, and weak variants that inter-operate.

 If there are no serious issues brought up in the next day or two, I'll
 push it to the development branch, since our current release process isn't
 following HEAD.

 Carl Eastlund



 _
   Racket Developers list:
   http://lists.racket-lang.org/dev

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-01 Thread Carl Eastlund
Hmm.  Well, partially, I wasn't sure how to document the methods, because
the relationships are complex, and because we don't have existing
terminology or documentation patterns for this.  I'm open to other
suggestions, and especially (though not exclusively) to patches.  For the
other part, I either should have made it as you say -- implement the
primitive ones and you get the others -- or else I should have clearly
documented the relationship somewhere.  I can't remember, now, if I thought
I had made the primitive ones sufficient, or if I knew there were others
you needed to implement, or if I just forgot to think that whole thing
through.

Do you have examples of which ones don't come for free with the primitive
methods?

Carl Eastlund


On Thu, Aug 1, 2013 at 6:27 PM, Stephen Chang stch...@ccs.neu.edu wrote:

 Just played a bit with gen:set. It looks great and in particular the
 fallback implementations are very convenient.

 One comment: the distinction between primitive methods and derived
 methods confused me somewhat. Can you explain the reasoning for
 determining which is which?

 For example, when I first read the docs, I thought that if I
 implemented the primitives, I would get the derived, but that's not
 the case since some of the derived methods depend on each other.
 Reading the docs more thoroughly, it sort of seems like there's an
 implicit separation along the lines of iterability, ie, derived sets
 are iterable since many of the derived methods require set-stream,
 but that's not exactly right either.


 On Thu, Jul 25, 2013 at 1:58 PM, Carl Eastlund c...@ccs.neu.edu wrote:
  After some fixes, mostly to contracts and documentation, I've pushed the
 new
  generics and set features to the master branch.
 
  Carl Eastlund
 
 
  On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund c...@ccs.neu.edu wrote:
 
  My work on adding gen:set, and related changes to define-generics and
  gen:dict, is ready for review and (hopefully) to push to the master
 branch.
  The branch moved in the process of cleaning things up, it's now at:
 
https://github.com/carl-eastlund/racket/tree/generics-from-scratch
 
  (The from scratch just refers to the process of rebuilding the git
  history, I didn't go out of my way to rewrite anything in the code base
 from
  scratch, although in some places a lot of code did move around.)
 
  What's new in the branch:
 
  - Generics now support a few new options
- #:fallbacks specifies fallback method implementations for instances
  with no implementation
- #:fast-defaults specifies instances on a fast path, useful for
  built-in types
- #:defined-predicate gives a more intuitive and efficient interface
  than #:defined-table
- #:derive-property allows generics to piggy-back on existing struct
  properties
 
  - Sets are now a generic datatype through gen:set
- lists are now sets
- the built-in set types are now documented as hash sets
- there are mutable and weak hash sets
- you can define new set types quickly with define-custom-set-types
- most set operations are now methods with fallbacks
- sets now support -copy and -clear operations, plus mutating [!]
  versions of operations
 
  - Dictionaries have a few changes
- new macro define-custom-hash-types [*]
- most dict operations are now methods with fallbacks
- dicts now support -copy, -clear, -clear!, and -empty? operations
 
  I've run some benchmarks and performance of the various generic
 operations
  are comparable to the current HEAD, so there should be no major
 performance
  changes with this patch.
 
  [*] I've added define-custom-hash-types and define-custom-set-types
 rather
  than just adding make-custom-set akin to make-custom-hash because
  make-custom-hash is hard to use.  The documented behavior -- that any
 custom
  hash is equal to any other created with the same bindings and
 predicates /
  hash functions -- was never true and can be expensive or at least
 tricky to
  implement.  It seemed more sensible to just remove the erroneous
  documentation on make-custom-hash, and add the definition form to create
  constructors for new, explicitly-compatible dict and set types.  Both
  definition forms bind predicates and constructors for new (set or dict)
  types with immutable, mutable, and weak variants that inter-operate.
 
  If there are no serious issues brought up in the next day or two, I'll
  push it to the development branch, since our current release process
 isn't
  following HEAD.
 
  Carl Eastlund
 
 
 
  _
Racket Developers list:
http://lists.racket-lang.org/dev
 


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-01 Thread Stephen Chang
 For the other part, I either should have made it as you say -- implement the 
  primitive ones and you get the others -- or else I should have clearly
 documented the relationship somewhere.

You did document the dependencies, but some of them are circular, ie
some derived rely on other derived. I'd definitely be happy to patch
things myself, but I guess I dont have a concrete complaint yet :),
only that the distinctions feel somewhat arbitrary and did not match
my initial intuition, which is why I'm looking for additional insight.


 Do you have examples of which ones don't come for free with the primitive
 methods?

Very few of the derived come free because most rely on set-stream,
but set-stream is not primitive which is why I thought there might
be a distinction between iterable sets and non-iterable.





 Carl Eastlund


 On Thu, Aug 1, 2013 at 6:27 PM, Stephen Chang stch...@ccs.neu.edu wrote:

 Just played a bit with gen:set. It looks great and in particular the
 fallback implementations are very convenient.

 One comment: the distinction between primitive methods and derived
 methods confused me somewhat. Can you explain the reasoning for
 determining which is which?

 For example, when I first read the docs, I thought that if I
 implemented the primitives, I would get the derived, but that's not
 the case since some of the derived methods depend on each other.
 Reading the docs more thoroughly, it sort of seems like there's an
 implicit separation along the lines of iterability, ie, derived sets
 are iterable since many of the derived methods require set-stream,
 but that's not exactly right either.


 On Thu, Jul 25, 2013 at 1:58 PM, Carl Eastlund c...@ccs.neu.edu wrote:
  After some fixes, mostly to contracts and documentation, I've pushed the
  new
  generics and set features to the master branch.
 
  Carl Eastlund
 
 
  On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund c...@ccs.neu.edu wrote:
 
  My work on adding gen:set, and related changes to define-generics and
  gen:dict, is ready for review and (hopefully) to push to the master
  branch.
  The branch moved in the process of cleaning things up, it's now at:
 
https://github.com/carl-eastlund/racket/tree/generics-from-scratch
 
  (The from scratch just refers to the process of rebuilding the git
  history, I didn't go out of my way to rewrite anything in the code base
  from
  scratch, although in some places a lot of code did move around.)
 
  What's new in the branch:
 
  - Generics now support a few new options
- #:fallbacks specifies fallback method implementations for instances
  with no implementation
- #:fast-defaults specifies instances on a fast path, useful for
  built-in types
- #:defined-predicate gives a more intuitive and efficient interface
  than #:defined-table
- #:derive-property allows generics to piggy-back on existing struct
  properties
 
  - Sets are now a generic datatype through gen:set
- lists are now sets
- the built-in set types are now documented as hash sets
- there are mutable and weak hash sets
- you can define new set types quickly with define-custom-set-types
- most set operations are now methods with fallbacks
- sets now support -copy and -clear operations, plus mutating [!]
  versions of operations
 
  - Dictionaries have a few changes
- new macro define-custom-hash-types [*]
- most dict operations are now methods with fallbacks
- dicts now support -copy, -clear, -clear!, and -empty? operations
 
  I've run some benchmarks and performance of the various generic
  operations
  are comparable to the current HEAD, so there should be no major
  performance
  changes with this patch.
 
  [*] I've added define-custom-hash-types and define-custom-set-types
  rather
  than just adding make-custom-set akin to make-custom-hash because
  make-custom-hash is hard to use.  The documented behavior -- that any
  custom
  hash is equal to any other created with the same bindings and
  predicates /
  hash functions -- was never true and can be expensive or at least
  tricky to
  implement.  It seemed more sensible to just remove the erroneous
  documentation on make-custom-hash, and add the definition form to
  create
  constructors for new, explicitly-compatible dict and set types.  Both
  definition forms bind predicates and constructors for new (set or dict)
  types with immutable, mutable, and weak variants that inter-operate.
 
  If there are no serious issues brought up in the next day or two, I'll
  push it to the development branch, since our current release process
  isn't
  following HEAD.
 
  Carl Eastlund
 
 
 
  _
Racket Developers list:
http://lists.racket-lang.org/dev
 


_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-08-01 Thread Carl Eastlund
Ah, yes, set-stream isn't primitive because it can be derived if you have
set-first and either set-rest or set-remove.  And I know there are
dependency cycles, this is intentional so that you can implement any one of
several related things, but most of them were supposed to go all the way
down to primitive methods (in some sense) if all else failed.

Would it be better to just remove the primitve / derived distinction,
since it's somewhat artificial, and leave it up to the individual method
descriptions?  Is there some better way I should be describing things?

Carl Eastlund


On Thu, Aug 1, 2013 at 6:51 PM, Stephen Chang stch...@ccs.neu.edu wrote:

  For the other part, I either should have made it as you say -- implement
 the  primitive ones and you get the others -- or else I should have
 clearly
  documented the relationship somewhere.

 You did document the dependencies, but some of them are circular, ie
 some derived rely on other derived. I'd definitely be happy to patch
 things myself, but I guess I dont have a concrete complaint yet :),
 only that the distinctions feel somewhat arbitrary and did not match
 my initial intuition, which is why I'm looking for additional insight.


  Do you have examples of which ones don't come for free with the
 primitive
  methods?

 Very few of the derived come free because most rely on set-stream,
 but set-stream is not primitive which is why I thought there might
 be a distinction between iterable sets and non-iterable.




 
  Carl Eastlund
 
 
  On Thu, Aug 1, 2013 at 6:27 PM, Stephen Chang stch...@ccs.neu.edu
 wrote:
 
  Just played a bit with gen:set. It looks great and in particular the
  fallback implementations are very convenient.
 
  One comment: the distinction between primitive methods and derived
  methods confused me somewhat. Can you explain the reasoning for
  determining which is which?
 
  For example, when I first read the docs, I thought that if I
  implemented the primitives, I would get the derived, but that's not
  the case since some of the derived methods depend on each other.
  Reading the docs more thoroughly, it sort of seems like there's an
  implicit separation along the lines of iterability, ie, derived sets
  are iterable since many of the derived methods require set-stream,
  but that's not exactly right either.
 
 
  On Thu, Jul 25, 2013 at 1:58 PM, Carl Eastlund c...@ccs.neu.edu wrote:
   After some fixes, mostly to contracts and documentation, I've pushed
 the
   new
   generics and set features to the master branch.
  
   Carl Eastlund
  
  
   On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund c...@ccs.neu.edu
 wrote:
  
   My work on adding gen:set, and related changes to define-generics and
   gen:dict, is ready for review and (hopefully) to push to the master
   branch.
   The branch moved in the process of cleaning things up, it's now at:
  
 https://github.com/carl-eastlund/racket/tree/generics-from-scratch
  
   (The from scratch just refers to the process of rebuilding the git
   history, I didn't go out of my way to rewrite anything in the code
 base
   from
   scratch, although in some places a lot of code did move around.)
  
   What's new in the branch:
  
   - Generics now support a few new options
 - #:fallbacks specifies fallback method implementations for
 instances
   with no implementation
 - #:fast-defaults specifies instances on a fast path, useful for
   built-in types
 - #:defined-predicate gives a more intuitive and efficient
 interface
   than #:defined-table
 - #:derive-property allows generics to piggy-back on existing
 struct
   properties
  
   - Sets are now a generic datatype through gen:set
 - lists are now sets
 - the built-in set types are now documented as hash sets
 - there are mutable and weak hash sets
 - you can define new set types quickly with define-custom-set-types
 - most set operations are now methods with fallbacks
 - sets now support -copy and -clear operations, plus mutating [!]
   versions of operations
  
   - Dictionaries have a few changes
 - new macro define-custom-hash-types [*]
 - most dict operations are now methods with fallbacks
 - dicts now support -copy, -clear, -clear!, and -empty? operations
  
   I've run some benchmarks and performance of the various generic
   operations
   are comparable to the current HEAD, so there should be no major
   performance
   changes with this patch.
  
   [*] I've added define-custom-hash-types and define-custom-set-types
   rather
   than just adding make-custom-set akin to make-custom-hash because
   make-custom-hash is hard to use.  The documented behavior -- that any
   custom
   hash is equal to any other created with the same bindings and
   predicates /
   hash functions -- was never true and can be expensive or at least
   tricky to
   implement.  It seemed more sensible to just remove the erroneous
   documentation on make-custom-hash, and add the definition form to
   

Re: [racket-dev] Generics updates

2013-08-01 Thread Stephen Chang
 Would it be better to just remove the primitve / derived distinction,
 since it's somewhat artificial, and leave it up to the individual method
 descriptions?  Is there some better way I should be describing things?

Ok I can see now that there's no easy way to organize the methods.

I think we should keep some distinction, since as a programmer it's
good to know exactly what methods I have to implement. However, to me
fallback implies that I should get it for free, so it seems most
intuitive if derived methods only depend on primitive methods. Then
for some subset of primitive methods that I implement, I should get
the derived methods that depend on those primitives. I'll have to
think more about what should be derived and primitive, but for now I
think the easiest thing is to edit the docs to move set-stream (or
some equivalent) into the primitive list?




 Carl Eastlund


 On Thu, Aug 1, 2013 at 6:51 PM, Stephen Chang stch...@ccs.neu.edu wrote:

  For the other part, I either should have made it as you say -- implement
  the  primitive ones and you get the others -- or else I should have
  clearly
  documented the relationship somewhere.

 You did document the dependencies, but some of them are circular, ie
 some derived rely on other derived. I'd definitely be happy to patch
 things myself, but I guess I dont have a concrete complaint yet :),
 only that the distinctions feel somewhat arbitrary and did not match
 my initial intuition, which is why I'm looking for additional insight.


  Do you have examples of which ones don't come for free with the
  primitive
  methods?

 Very few of the derived come free because most rely on set-stream,
 but set-stream is not primitive which is why I thought there might
 be a distinction between iterable sets and non-iterable.




 
  Carl Eastlund
 
 
  On Thu, Aug 1, 2013 at 6:27 PM, Stephen Chang stch...@ccs.neu.edu
  wrote:
 
  Just played a bit with gen:set. It looks great and in particular the
  fallback implementations are very convenient.
 
  One comment: the distinction between primitive methods and derived
  methods confused me somewhat. Can you explain the reasoning for
  determining which is which?
 
  For example, when I first read the docs, I thought that if I
  implemented the primitives, I would get the derived, but that's not
  the case since some of the derived methods depend on each other.
  Reading the docs more thoroughly, it sort of seems like there's an
  implicit separation along the lines of iterability, ie, derived sets
  are iterable since many of the derived methods require set-stream,
  but that's not exactly right either.
 
 
  On Thu, Jul 25, 2013 at 1:58 PM, Carl Eastlund c...@ccs.neu.edu wrote:
   After some fixes, mostly to contracts and documentation, I've pushed
   the
   new
   generics and set features to the master branch.
  
   Carl Eastlund
  
  
   On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund c...@ccs.neu.edu
   wrote:
  
   My work on adding gen:set, and related changes to define-generics
   and
   gen:dict, is ready for review and (hopefully) to push to the master
   branch.
   The branch moved in the process of cleaning things up, it's now at:
  
 https://github.com/carl-eastlund/racket/tree/generics-from-scratch
  
   (The from scratch just refers to the process of rebuilding the git
   history, I didn't go out of my way to rewrite anything in the code
   base
   from
   scratch, although in some places a lot of code did move around.)
  
   What's new in the branch:
  
   - Generics now support a few new options
 - #:fallbacks specifies fallback method implementations for
   instances
   with no implementation
 - #:fast-defaults specifies instances on a fast path, useful for
   built-in types
 - #:defined-predicate gives a more intuitive and efficient
   interface
   than #:defined-table
 - #:derive-property allows generics to piggy-back on existing
   struct
   properties
  
   - Sets are now a generic datatype through gen:set
 - lists are now sets
 - the built-in set types are now documented as hash sets
 - there are mutable and weak hash sets
 - you can define new set types quickly with
   define-custom-set-types
 - most set operations are now methods with fallbacks
 - sets now support -copy and -clear operations, plus mutating [!]
   versions of operations
  
   - Dictionaries have a few changes
 - new macro define-custom-hash-types [*]
 - most dict operations are now methods with fallbacks
 - dicts now support -copy, -clear, -clear!, and -empty? operations
  
   I've run some benchmarks and performance of the various generic
   operations
   are comparable to the current HEAD, so there should be no major
   performance
   changes with this patch.
  
   [*] I've added define-custom-hash-types and define-custom-set-types
   rather
   than just adding make-custom-set akin to make-custom-hash because
   make-custom-hash is hard to use.  The documented behavior 

Re: [racket-dev] Generics updates

2013-08-01 Thread Carl Eastlund
No, that doesn't work.  If someone implements, say, an efficient subset?
test, then set=? should use that rather than iterating using set-stream
and set-member?.  You should use the highest-level methods you can, in
order to get the most out of an implementation.  Which is why I made all
the fallback implementations I did, to give implementers the best
flexibility possible for getting a good implementation of all methods for
the minimum possible effort on their part.

Similarly, I don't want to make set-stream primitive, because if someone
does implement set-first and set-rest, it should be derivable.

Carl Eastlund


On Thu, Aug 1, 2013 at 7:26 PM, Stephen Chang stch...@ccs.neu.edu wrote:

  Would it be better to just remove the primitve / derived distinction,
  since it's somewhat artificial, and leave it up to the individual method
  descriptions?  Is there some better way I should be describing things?

 Ok I can see now that there's no easy way to organize the methods.

 I think we should keep some distinction, since as a programmer it's
 good to know exactly what methods I have to implement. However, to me
 fallback implies that I should get it for free, so it seems most
 intuitive if derived methods only depend on primitive methods. Then
 for some subset of primitive methods that I implement, I should get
 the derived methods that depend on those primitives. I'll have to
 think more about what should be derived and primitive, but for now I
 think the easiest thing is to edit the docs to move set-stream (or
 some equivalent) into the primitive list?



 
  Carl Eastlund
 
 
  On Thu, Aug 1, 2013 at 6:51 PM, Stephen Chang stch...@ccs.neu.edu
 wrote:
 
   For the other part, I either should have made it as you say --
 implement
   the  primitive ones and you get the others -- or else I should have
   clearly
   documented the relationship somewhere.
 
  You did document the dependencies, but some of them are circular, ie
  some derived rely on other derived. I'd definitely be happy to patch
  things myself, but I guess I dont have a concrete complaint yet :),
  only that the distinctions feel somewhat arbitrary and did not match
  my initial intuition, which is why I'm looking for additional insight.
 
 
   Do you have examples of which ones don't come for free with the
   primitive
   methods?
 
  Very few of the derived come free because most rely on set-stream,
  but set-stream is not primitive which is why I thought there might
  be a distinction between iterable sets and non-iterable.
 
 
 
 
  
   Carl Eastlund
  
  
   On Thu, Aug 1, 2013 at 6:27 PM, Stephen Chang stch...@ccs.neu.edu
   wrote:
  
   Just played a bit with gen:set. It looks great and in particular the
   fallback implementations are very convenient.
  
   One comment: the distinction between primitive methods and
 derived
   methods confused me somewhat. Can you explain the reasoning for
   determining which is which?
  
   For example, when I first read the docs, I thought that if I
   implemented the primitives, I would get the derived, but that's not
   the case since some of the derived methods depend on each other.
   Reading the docs more thoroughly, it sort of seems like there's an
   implicit separation along the lines of iterability, ie, derived sets
   are iterable since many of the derived methods require set-stream,
   but that's not exactly right either.
  
  
   On Thu, Jul 25, 2013 at 1:58 PM, Carl Eastlund c...@ccs.neu.edu
 wrote:
After some fixes, mostly to contracts and documentation, I've
 pushed
the
new
generics and set features to the master branch.
   
Carl Eastlund
   
   
On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund c...@ccs.neu.edu
wrote:
   
My work on adding gen:set, and related changes to define-generics
and
gen:dict, is ready for review and (hopefully) to push to the
 master
branch.
The branch moved in the process of cleaning things up, it's now
 at:
   
   
 https://github.com/carl-eastlund/racket/tree/generics-from-scratch
   
(The from scratch just refers to the process of rebuilding the
 git
history, I didn't go out of my way to rewrite anything in the code
base
from
scratch, although in some places a lot of code did move around.)
   
What's new in the branch:
   
- Generics now support a few new options
  - #:fallbacks specifies fallback method implementations for
instances
with no implementation
  - #:fast-defaults specifies instances on a fast path, useful
 for
built-in types
  - #:defined-predicate gives a more intuitive and efficient
interface
than #:defined-table
  - #:derive-property allows generics to piggy-back on existing
struct
properties
   
- Sets are now a generic datatype through gen:set
  - lists are now sets
  - the built-in set types are now documented as hash sets
  - there are mutable and weak hash sets
  - you can define new set types 

Re: [racket-dev] Generics updates

2013-07-25 Thread Carl Eastlund
After some fixes, mostly to contracts and documentation, I've pushed the
new generics and set features to the master branch.

Carl Eastlund


On Tue, Jul 23, 2013 at 11:37 AM, Carl Eastlund c...@ccs.neu.edu wrote:

 My work on adding gen:set, and related changes to define-generics and
 gen:dict, is ready for review and (hopefully) to push to the master
 branch.  The branch moved in the process of cleaning things up, it's now at:

   https://github.com/carl-eastlund/racket/tree/generics-from-scratch

 (The from scratch just refers to the process of rebuilding the git
 history, I didn't go out of my way to rewrite anything in the code base
 from scratch, although in some places a lot of code did move around.)

 What's new in the branch:

 - Generics now support a few new options
   - #:fallbacks specifies fallback method implementations for instances
 with no implementation
   - #:fast-defaults specifies instances on a fast path, useful for
 built-in types
   - #:defined-predicate gives a more intuitive and efficient interface
 than #:defined-table
   - #:derive-property allows generics to piggy-back on existing struct
 properties

 - Sets are now a generic datatype through gen:set
   - lists are now sets
   - the built-in set types are now documented as hash sets
   - there are mutable and weak hash sets
   - you can define new set types quickly with define-custom-set-types
   - most set operations are now methods with fallbacks
   - sets now support -copy and -clear operations, plus mutating [!]
 versions of operations

 - Dictionaries have a few changes
   - new macro define-custom-hash-types [*]
   - most dict operations are now methods with fallbacks
   - dicts now support -copy, -clear, -clear!, and -empty? operations

 I've run some benchmarks and performance of the various generic operations
 are comparable to the current HEAD, so there should be no major performance
 changes with this patch.

 [*] I've added define-custom-hash-types and define-custom-set-types rather
 than just adding make-custom-set akin to make-custom-hash because
 make-custom-hash is hard to use.  The documented behavior -- that any
 custom hash is equal to any other created with the same bindings and
 predicates / hash functions -- was never true and can be expensive or at
 least tricky to implement.  It seemed more sensible to just remove the
 erroneous documentation on make-custom-hash, and add the definition form to
 create constructors for new, explicitly-compatible dict and set types.
 Both definition forms bind predicates and constructors for new (set or
 dict) types with immutable, mutable, and weak variants that inter-operate.

 If there are no serious issues brought up in the next day or two, I'll
 push it to the development branch, since our current release process isn't
 following HEAD.

 Carl Eastlund

_
  Racket Developers list:
  http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-07-24 Thread Tobias Hammer
I really like the new set features, especially mutable sets and lists as  
sets.


Two things i have notices:
* The docs for set-intersect seem a bit mixed up with set-union stuff
* I could not get set-intersect on lists working, what i've tried

- (set-intersect '(1 2 3) '(2 3 4))
; set-add: contract violation
;   expected: set?
;   given: 2

- (set-intersect (list-set '(1 2 3)) '(2 3 4))
; set-intersect: set arguments have incompatible equivalence predicates
;   first set: (set 1 2 3)
;   incompatible set: '(2 3 4)

Tobias


On Tue, 23 Jul 2013 17:37:15 +0200, Carl Eastlund c...@ccs.neu.edu wrote:


My work on adding gen:set, and related changes to define-generics and
gen:dict, is ready for review and (hopefully) to push to the master
branch.  The branch moved in the process of cleaning things up, it's now  
at:


  https://github.com/carl-eastlund/racket/tree/generics-from-scratch

(The from scratch just refers to the process of rebuilding the git
history, I didn't go out of my way to rewrite anything in the code base
from scratch, although in some places a lot of code did move around.)

What's new in the branch:

- Generics now support a few new options
  - #:fallbacks specifies fallback method implementations for instances
with no implementation
  - #:fast-defaults specifies instances on a fast path, useful for
built-in types
  - #:defined-predicate gives a more intuitive and efficient interface  
than

#:defined-table
  - #:derive-property allows generics to piggy-back on existing struct
properties

- Sets are now a generic datatype through gen:set
  - lists are now sets
  - the built-in set types are now documented as hash sets
  - there are mutable and weak hash sets
  - you can define new set types quickly with define-custom-set-types
  - most set operations are now methods with fallbacks
  - sets now support -copy and -clear operations, plus mutating [!]
versions of operations

- Dictionaries have a few changes
  - new macro define-custom-hash-types [*]
  - most dict operations are now methods with fallbacks
  - dicts now support -copy, -clear, -clear!, and -empty? operations

I've run some benchmarks and performance of the various generic  
operations
are comparable to the current HEAD, so there should be no major  
performance

changes with this patch.

[*] I've added define-custom-hash-types and define-custom-set-types  
rather

than just adding make-custom-set akin to make-custom-hash because
make-custom-hash is hard to use.  The documented behavior -- that any
custom hash is equal to any other created with the same bindings and
predicates / hash functions -- was never true and can be expensive or at
least tricky to implement.  It seemed more sensible to just remove the
erroneous documentation on make-custom-hash, and add the definition form  
to

create constructors for new, explicitly-compatible dict and set types.
Both definition forms bind predicates and constructors for new (set or
dict) types with immutable, mutable, and weak variants that  
inter-operate.


If there are no serious issues brought up in the next day or two, I'll  
push

it to the development branch, since our current release process isn't
following HEAD.

Carl Eastlund



--
-
Tobias Hammer
DLR / Robotics and Mechatronics Center (RMC)
Muenchner Str. 20, D-82234 Wessling
Tel.: 08153/28-1487
Mail: tobias.ham...@dlr.de
_
 Racket Developers list:
 http://lists.racket-lang.org/dev


Re: [racket-dev] Generics updates

2013-07-24 Thread Carl Eastlund
Thanks for those pointers, Tobias, I'll get those fixed.

Carl Eastlund

On Wed, Jul 24, 2013 at 1:34 PM, Tobias Hammer tobias.ham...@dlr.de wrote:

 I really like the new set features, especially mutable sets and lists as
 sets.

 Two things i have notices:
 * The docs for set-intersect seem a bit mixed up with set-union stuff
 * I could not get set-intersect on lists working, what i've tried

 - (set-intersect '(1 2 3) '(2 3 4))
 ; set-add: contract violation
 ;   expected: set?
 ;   given: 2

 - (set-intersect (list-set '(1 2 3)) '(2 3 4))
 ; set-intersect: set arguments have incompatible equivalence predicates
 ;   first set: (set 1 2 3)
 ;   incompatible set: '(2 3 4)

 Tobias



 On Tue, 23 Jul 2013 17:37:15 +0200, Carl Eastlund c...@ccs.neu.edu wrote:

  My work on adding gen:set, and related changes to define-generics and
 gen:dict, is ready for review and (hopefully) to push to the master
 branch.  The branch moved in the process of cleaning things up, it's now
 at:

   
 https://github.com/carl-**eastlund/racket/tree/generics-**from-scratchhttps://github.com/carl-eastlund/racket/tree/generics-from-scratch

 (The from scratch just refers to the process of rebuilding the git
 history, I didn't go out of my way to rewrite anything in the code base
 from scratch, although in some places a lot of code did move around.)

 What's new in the branch:

 - Generics now support a few new options
   - #:fallbacks specifies fallback method implementations for instances
 with no implementation
   - #:fast-defaults specifies instances on a fast path, useful for
 built-in types
   - #:defined-predicate gives a more intuitive and efficient interface
 than
 #:defined-table
   - #:derive-property allows generics to piggy-back on existing struct
 properties

 - Sets are now a generic datatype through gen:set
   - lists are now sets
   - the built-in set types are now documented as hash sets
   - there are mutable and weak hash sets
   - you can define new set types quickly with define-custom-set-types
   - most set operations are now methods with fallbacks
   - sets now support -copy and -clear operations, plus mutating [!]
 versions of operations

 - Dictionaries have a few changes
   - new macro define-custom-hash-types [*]
   - most dict operations are now methods with fallbacks
   - dicts now support -copy, -clear, -clear!, and -empty? operations

 I've run some benchmarks and performance of the various generic operations
 are comparable to the current HEAD, so there should be no major
 performance
 changes with this patch.

 [*] I've added define-custom-hash-types and define-custom-set-types rather
 than just adding make-custom-set akin to make-custom-hash because
 make-custom-hash is hard to use.  The documented behavior -- that any
 custom hash is equal to any other created with the same bindings and
 predicates / hash functions -- was never true and can be expensive or at
 least tricky to implement.  It seemed more sensible to just remove the
 erroneous documentation on make-custom-hash, and add the definition form
 to
 create constructors for new, explicitly-compatible dict and set types.
 Both definition forms bind predicates and constructors for new (set or
 dict) types with immutable, mutable, and weak variants that inter-operate.

 If there are no serious issues brought up in the next day or two, I'll
 push
 it to the development branch, since our current release process isn't
 following HEAD.

 Carl Eastlund



 --
 --**---
 Tobias Hammer
 DLR / Robotics and Mechatronics Center (RMC)
 Muenchner Str. 20, D-82234 Wessling
 Tel.: 08153/28-1487
 Mail: tobias.ham...@dlr.de


_
  Racket Developers list:
  http://lists.racket-lang.org/dev