Dylan implementation question 
Author Message
 Dylan implementation question

I have a question regarding mandatory keyword defaults; the DRM seems
to contain an inconsistency:

On p. 89, in the second paragraph under Keyword Parameters, we have,
"If no expression is specified, the parameter corresponding to an
unsupplied keyword argument is initialized to #f."

Also, on p. 91, under Types for Keyword Parameters, we have, "If a
keyword parameter is given a type, if #f is not an instance of that
type, and if the keyword parameter is not given a default value, then
the keyword parameter is essentially required."

So far so good. The implication of the above statements is clear: If a
generic function recognizes a keyword, then when the corresponding
method is invoked, the keyword parameter will be bound as follows:

a) If a keyword argument is passed, the keyword parameter will be
bound to the value of the argument.

b) If the keyword argument is not passed, the keyword parameter will
be bound to the value of the keyword's default expression, if any;
otherwise it will be bound to #f.

The net result is that the keyword parameter will always be bound to
something; it will never be unbound.

But now let's look at the definition for the element function, on p.
300: "If no element is associated with key, then the behavior of
element depends on whether it was called with a default argument: if a
default argument was passed, its value is returned; otherwise, an
error is signaled."

Now we have a problem. The specified behavior of element requires that
it knows whether or not a value for default was passed, yet the
keyword parameter binding specification says that a value will
_always_ be bound to default, whether or not a value was explicitly
passed. So how can element tell the difference?

Any enlightenment is welcome.

-Steve Schafer



Sat, 21 Aug 2004 03:41:37 GMT  
 Dylan implementation question
By defaulting #"default" to a value that can impossibly guessed in another
module. This could be a dynamically consed value (bound to a constant) or
some <function> value that is not exported. Then \~== with that value gives
you the answer.

    Gabor

----------

Quote:


>Subject: Dylan implementation question
>Date: Mon, 4. M?r 2002 20:45 Uhr

> Now we have a problem. The specified behavior of element requires that
> it knows whether or not a value for default was passed, yet the
> keyword parameter binding specification says that a value will
> _always_ be bound to default, whether or not a value was explicitly
> passed. So how can element tell the difference?

> Any enlightenment is welcome.



Sat, 21 Aug 2004 05:28:12 GMT  
 Dylan implementation question

Quote:
> But now let's look at the definition for the element function, on p.
> 300: "If no element is associated with key, then the behavior of
> element depends on whether it was called with a default argument: if a
> default argument was passed, its value is returned; otherwise, an
> error is signaled."

> Now we have a problem. The specified behavior of element requires that
> it knows whether or not a value for default was passed, yet the
> keyword parameter binding specification says that a value will
> _always_ be bound to default, whether or not a value was explicitly
> passed. So how can element tell the difference?

The usual answer is to do this:

define inline sealed method element
    (ht :: <table>, key :: <object>, #key default: default = $not-supplied)
 => (result :: <object>);
  // ...
end method element;

The $not-supplied token is an internal constant that users can't
normally pass around, since its name is not exported.  :

define class <not-supplied-marker> (<object>)
end;

define constant $not-supplied :: <not-supplied-marker>
    = make(<not-supplied-marker>);

So to determine if a default: argument was given, the element method
need only check to see if default == $not-supplied.

-Peter-



Sat, 21 Aug 2004 05:29:25 GMT  
 Dylan implementation question

Quote:
> The usual answer is to do this:

> define inline sealed method element
>     (ht :: <table>, key :: <object>, #key default: default = $not-supplied)
>  => (result :: <object>);
>   // ...
> end method element;

> The $not-supplied token is an internal constant that users can't
> normally pass around, since its name is not exported.  :

> define class <not-supplied-marker> (<object>)
> end;

> define constant $not-supplied :: <not-supplied-marker>
>     = make(<not-supplied-marker>);

Thanks to all for the hint--it makes sense now. I guess the only
additional complication is that the presence of specializers attached
to keyword parameters might require the use of several different
"not-supplied" constants of different types.

-Steve Schafer



Sat, 21 Aug 2004 14:26:13 GMT  
 Dylan implementation question

Quote:


> > The usual answer is to do this:

> > define inline sealed method element
> >     (ht :: <table>, key :: <object>, #key default: default = $not-supplied)
> >  => (result :: <object>);
> >   // ...
> > end method element;

> > The $not-supplied token is an internal constant that users can't
> > normally pass around, since its name is not exported.  :

> > define class <not-supplied-marker> (<object>)
> > end;

> > define constant $not-supplied :: <not-supplied-marker>
> >     = make(<not-supplied-marker>);

> Thanks to all for the hint--it makes sense now. I guess the only
> additional complication is that the presence of specializers attached
> to keyword parameters might require the use of several different
> "not-supplied" constants of different types.

> -Steve Schafer

Yes, this is probably a problem then.
If the keyword parameter has type <foo> than the marker must be
an instance of a "secret" subclass. Achieving this may be impossible
because <foo> is sealed or too complicated to create an instance of
(e.g. init protocol contains some init keywords etc. that are hard to
supply or cause unwanted side-effects).

In such a case one could declare
type-union(<foo>, <not-supplied-marker>) as the type of the keyword argument.

        Gabor

  smime.p7s
2K Download


Sun, 22 Aug 2004 01:37:38 GMT  
 Dylan implementation question

Quote:
> Thanks to all for the hint--it makes sense now. I guess the only
> additional complication is that the presence of specializers attached
> to keyword parameters might require the use of several different
> "not-supplied" constants of different types.

That's not usually necessary.  You could just use a type-union:

define method foo(bar :: <bar>,
                  #key baz :: type-union(<baz>, singleton($not-supplied))
                     = $not-supplied);
  // ...
  if($baz ~== $not-supplied)
    // at this point the compiler knows baz must be of type <baz>
    // ...
  end if;
  // ...
end method;

-Peter-



Sun, 22 Aug 2004 06:10:04 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. another Dylan implementation?

2. Free Dylan implementations?

3. Dylan implementation tips

4. Status of Dylan implementations

5. Status of Dylan implementations

6. Which public domain Dylan implementation ?

7. Dylan Implementations

8. Dylan Implementations

9. Implementations of Dylan

10. Implementation of Dylan on PC?

11. Where is dylan implementation?

12. Dylan-implementation in CL?

 

 
Powered by phpBB® Forum Software