On Wed, Jul 25, 2012 at 9:36 AM, Mariano Guerra
<
luismari...@gmail.com> wrote:
>
> one proposal (feel free to analyze it's unlispiness :)
>
> a runtime set of functions:
>
> (set-meta <thing> <key-value-pairs>)
>
> sets the values in key-value-pairs as metadata for thing, thing can be
> any type in squim
>
> (get-meta <thing> key [default])
>
> return metadata associated with key in thing, if not found return
> default if provided, some default value if not*
>
My javascript is pretty weak, but I assume you mean attaching this in
some kind of hidden slot in the object itself at runtime? There is
nothing unlispy about that, as a matter of fact in older lisps (and
also in CL) symbols had what was called a property list, which was
something like that.
Another implementation option is to use a hashtable This is actually
doable in klisp, thanks to Oto Havle and his work on exposing the
internal (eq? based) hashtables api. The api is still not final, but
it exposes hashtables using eq? as the equality predicate, and so you
can use a global table to store per object metadata (but please be
aware that some immutable objects can't be copied, e.g. All string=?
immutable strings are eq? to each other, so you may want to use
mutable strings (or encapsulated immutable strings) in that case). If
you follow this route, however, you should take into account that the
global table will not allow gc to reclaim objects in the table, even
if there are no other references. You can avoid this with the use of
weak tables, something internal klisp tables have, but still isn't
exposed in the current api.
> but this still doesn't solve the problem of attaching metadata in the
> code at parse time and have it serialized again, for this I propose an
> extension to the syntax (maybe only for squim)
>
> (<thing> #{key1 value1 key2 value2})
>
> will attach the set of key values to thing (the element on the left of #{}
>
Haha, This topic comes time and time again, it's like it's following
me. Since before I started klisp, the main hole of the Kernel Report
I wanted to address is the fact that there is no way to customize
read/write/eval/eq?/equal?, neither for new objects types
(encapsulations) nor for primitive types. I always leaned to generic
functions/multi-methods as a catch all solution, but as the Report
mentions, this is just one possible solution.
Of course read just needs a way to know about syntax extension and
what to do with them, and write can be solved with single-dispatch on
its argument.
As for external representations, I favour the following syntax for
extensions to Kernel:
#<thing>(obj1 obj2 ...)
and
#<thing>
The writer is trivially extended to support this. As for the reader,
when it sees this it can select a combiner based on <thing> and pass
it the (unevaluated) list as arguments to it. The combiner would
return the object just read or throw an error. I feel this is pretty
flexible and consistent with the existing syntax. For example it
could be used for vectors ("#vector(elem1 elem2 ...)", or like in
scheme just "#(elem1 elem2 ...)"), hashtables ("#hashtable(string=?
("key1" <value1>) ("key2" <value2>))"), new constants ("#pi",
"#null"), etc.
A more general solution of course are reader macros, but I think they
are overkill for just allowing external representations for new object
types.
Only two new applicatives are needed:
(add-output-representation <type-predicate?> <format-applicative>)
(add-input-representation <type-symbol> has-list? <constructor-applcative>)
where format-applicative could either return a string with the
external representation, or directly write to the output stream,
<type-symbol> is the symbol after "#" for this type, has-list? is a
boolean indicating if this type needs a list after <symbol> and
<constructor-applicative> takes the list or no arguments (depending on
has-list?) and returns the object to read.
> * nil, inert and ignore don't seem to fit the solution, is there a
> "kernel" or "scheme" way to handle this? fail?
If you mean that they are singleton constants and so can't have
different metadata for different appearances then you are correct.
The only solution is to not use singletons for them! The downside is
that you must allocate them on the heap as any other objects which may
be a very high price to pay, that's for you to decide. Depending on
your implementation you may be able to use the singleton constants by
default and just replace the ones who have metadata attached...
This is just from the top of my head, let me know if it was of any help.
Regards,
Andres Navarro