Re: Getl and maps behavior?

2008-08-22 Thread Alexander Burger
Hi Tomas,

> Isn't it just because it was implemented this way?  I mean these
> functions could be implemented to behave the same way even if getl
> returned a list of (property-name . property-value) which in this case

Ah, there is a misunderstanding. I was not talking especially about
'getl', but about how properties are implemented in general. It is
important, IMHO, that they are of the form (value . key) internally.

'getl' simply returns the property list as it is.

Surely it would have been possible to have 'getl' return a list of (key
. value) pairs, but this would have involved an additional level of
'cons'ing, creating unnecessary garbage.


> :(put 'A 'counter 0)
> -> 0
> : (put 'A 'list (1 2 3 4))
> -> (1 2 3 4)
> : (getl 'A)
> -> (((1 2 3 4) . list) (0 . counter)) # currently
> -> ((list . (1 2 3 4)) (counter . 0)) # I would expect this?
> 
> Or, how is the order inside pairs for getl/putl important to these
> functions?

If you use those functions directly on the result of 'getl', yes. But
this was not the intention, and I think I never did it.

The interesting point is to apply these functions directly to the cells
of a property list as returned by 'prop' or '::', as described
previously as (inc (:: counter)) or (pop (:: list)).

Having list cells behave like variables (by referring to their CAR
parts) is a very useful feature. Not only for properties, but also for
other list structures.

   : (setq L (1 2 3 4 5 6 7 8 9))
   -> (1 2 3 4 5 6 7 8 9)

   : (nth L 6)   
   -> (6 7 8 9)

   : (inc (nth L 6) 100)
   -> 106

   : (set (nth L 9) 777)
   -> 777

   : L  
   -> (1 2 3 4 5 106 7 8 777)



> I see, you think it is more useful to search for a given value and I
> thought it was more useful to search for a given property (even though

This is available anyway, with 'get', ':' etc.


> How and what for would you use assoc in your example?

In fact, I never needed that ;-)

But for the matter of an example:

   : (mapc '((Key Val) (put 'A Key Val)) '(a b c d e f g) (1 2 3 4 5 6 7))
   -> 7

   : (show 'A)
   A NIL
  g 7
  f 6
  e 5
  d 4
  c 3
  b 2
  a 1
   -> A

   : (get 'A 'd)
   -> 4

   : (assoc 4 (getl 'A))
   -> (4 . d)


> Sometimes a list of (key . value) is needed (e.g. a list of attributes
> for xml function) and in those cases, if I use getl in my code, I need
> to "swap" car and cdr values which is rather inconvenient.

I think 'getl' is not as important or useful as you seem to assume. It
always returns the _whole_ property list, and this may contain other
irrelevant data (as, for example, also Pilog stores rules in symbol
properties, and the debug environment file names and line numbers).

'getl' was primarily intended as the counterpart to 'putl', allowing a
fast cloning of symbols, or aid in debugging.

For application-relevant data it is much more common to use explicit
association lists. Assoc-lists were also the motivation to use the above
structure for xml attributes. They are more flexible than property
lists, because you can control aspects like the order of their elements,
or how you search them (with 'assoc', 'asoq', 'find' etc). Property
lists change their order on a last-recently used schema.


> I was thinking about XML data binding, representing XML using symbols
> instead of lists and that was where getl surprized me.  It is not an
> issue though, just unexpected surprice;-)

I would say it is best to use symbols when you have well defined,
independent properties, and association lists when you need a whole list
for a given operation.

> # convert xml "list" (as returned by xml function) to xml "symbol"
> ...
> # convert xml "symbol" to xml "list" (as consumed by xml function)
> ...

As I said, this might give surprising results if you by chance encounter
symbols used somewhere else in the system. Try (getl 'select)!



> The advantage of this approach is that I can use all those property
> access functions instead of searching for elements & attributes in a

Searching with 'assoc' or 'asoq' is about as convenient as using 'put'
and 'get'. In addition, you can use the full set of list manipulation
functions on association lists, while with property lists you are
limited to the 'get' and 'put' function family, or need the overhead of
'getl' and 'putl'. This overhead is relatively large, as the whole
property list needs to be copied.

> list.  Also, other useful stuff could be added to a symbol
> representing an XML element, e.g. indices for accessing items of a
> list hold by a property in a specific order.

Here, too, I believe that (nested) lists structures are more powerful.
But it all depends, of course. It is always worth experimenting around a
little.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Getl and maps behavior?

2008-08-22 Thread Tomas Hlavaty
Hi Henrik,

sorry I am not following in your thread but I do not seem to be
getting all emails from the mailing list.  Is anybody experiencing
similar problem?

> As far as I've been able to see any kind of key is double quoted in
> the json string (so that is what happens now), at least in the
> examples I've looked at.

You are right.

> Now the question is, should we do basic objects when converting from
> json or paired lists. Basic objects are possible in that direction
> but that would then "break" with the rule of only accepting +Entity
> objects and paired lists for encoding.

> Can anyone see a scenario where the above way of getting the
> relations would not work?

I think (isa '+Relation (car Prop)) works if you use picolisp OO
concepts, it won't work in general for any object/symbol.

Restricting yourself that way can be convenient but not necessary.

> In any case, the above generates the correct output with
> {..."descr": false} at the end of the json string.

Why is "descr" as false?  Would not it be better to output:

{"name": "PC", "id": "123"}

What if you have a js gui field which validates its input and expects
true|false|undefined (as don't care or unspecified)?

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Getl and maps behavior?

2008-08-22 Thread Tomas Hlavaty
Hi Alex,

> Most of all, a cell can be passed to functions that expect a variable
> 'var' argument, like 'set', 'inc', 'pop', and many more. This is also
> the reason for the property functions 'prop' and '::'.
>
>: (put 'A 'counter 0)
>-> 0
>
>: (put 'A 'list (1 2 3 4))
>-> (1 2 3 4)
>
>: (with 'A (inc (:: counter)))
>-> 1
>
>: (pop (prop 'A 'list))   
>-> 1
>
>: (show 'A)
>A NIL
>   list (2 3 4)
>   counter 1
>-> A

Isn't it just because it was implemented this way?  I mean these
functions could be implemented to behave the same way even if getl
returned a list of (property-name . property-value) which in this case
would be:

:(put 'A 'counter 0)
-> 0
: (put 'A 'list (1 2 3 4))
-> (1 2 3 4)
: (getl 'A)
-> (((1 2 3 4) . list) (0 . counter)) # currently
-> ((list . (1 2 3 4)) (counter . 0)) # I would expect this?

Or, how is the order inside pairs for getl/putl important to these
functions?

> Another reason is that a property list could be searched for a given
> value with 'assoc'.

I see, you think it is more useful to search for a given value and I
thought it was more useful to search for a given property (even though
there are other functions but they don't work with the list of
properties as a whole).

How and what for would you use assoc in your example?

What information would you get if you found that some property has a
given value and how/what for would you use this information?  Also,
values can be "random" from a programmer point of view as opposed to
keys (usually) and a few properties can have the same value; in that
case assoc fails to be useful:

: (assoc 0 '((0 . list) (0 . counter)))
-> (0 . list)


Sometimes a list of (key . value) is needed (e.g. a list of attributes
for xml function) and in those cases, if I use getl in my code, I need
to "swap" car and cdr values which is rather inconvenient.

Am I missing something?


I was thinking about XML data binding, representing XML using symbols
instead of lists and that was where getl surprized me.  It is not an
issue though, just unexpected surprice;-)

# convert xml "list" (as returned by xml function) to xml "symbol"
(de xml2sym (S X)
   (if S
  (let (E (car X) A (cadr X) B (cddr X) G (group B))
 (for H G
(let E2 (car H)
   (if (<= (length (cdr H)) 1)
  (for I (cdr H)
 (if (<= (length (cdr I)) 1)
(put S E2 (cadr I))
(put S E2 (xml2sym (new) (cons E2 I)
  (for I (cdr H)
 (if (<= (length (cdr I)) 1)
(put S E2 (conc (get S E2) (list (cadr I
(put S E2 (conc (get S E2)
(list (xml2sym (new) (cons E2 
I))
 S)
  (when X
 (let (R (new))
(put R (car X) (xml2sym (new) X))
R

# convert xml "symbol" to xml "list" (as consumed by xml function)
(de sym2xml (S)
   (let P (car (getl S))
  (_sym2xml (car P) (cdr P

(de _sym2xml (S E)
   (if (or (num? S) (not (getl S)))
  (list E NIL S)
  (let (N (get S '@@ns)
C (filter '((X) (not (pat? (cdr X (getl S))
A (filter '((X) (and (pat? (cdr X)) (<> '@@ns (cdr X (getl S)))
 (make
(link
   (if N (intern (pack N ': E)) E)
   (reverse
  (mapcar
 '((X) (cons (intern (pack (cdr (chop (cdr X) (car X)))
 A)))
(for I (reverse C)
   (if (lst? (car I))
  (for J (car I)
 (link (_sym2xml J (cdr I
  (link (_sym2xml (car I) (cdr I)

(de xload (F)
   (xml2sym NIL (in F (xml

(de xwrite (S)
   (xml? T) (xml (sym2xml S)))

(de xsave (F S)
   (out F (xwrite S)))

To see how it works, run something like:

(setq X (xload "my.xml"))
(show X) ...
(xsave "my2.xml" X)

The advantage of this approach is that I can use all those property
access functions instead of searching for elements & attributes in a
list.  Also, other useful stuff could be added to a symbol
representing an XML element, e.g. indices for accessing items of a
list hold by a property in a specific order.

Thanks,

Tomas
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: gui +Radio

2008-08-22 Thread Tomas Hlavaty
Hi Alex,

> 1. (default .. NIL) has no effect, (off *Radio) might be more
> appropriate.

I still don't have all those picolisp functions under my skin :-(

Thinking about it though, this line is probably unnecessary because
*Radio is never used as a global variable but only dynamically bound
while a form is rendered, so it does not have to be "declared" in
picolisp.

> But the actual problem I see is using a global variable.  The
> difficult question is *when* to clear that variable, so that it
> works also when the page is reloaded (possibly with a different
> status and layout), when the browser back-button is pressed, or
> during JavsScript postings.

Sorry for confusion.  It is not really a global variable.  I should
have given a better example of how it is supposed to be used:

(let *Radio NIL
   (form NIL
  ...
  (gui '(+Radio) "group1" "value1a")
  ...
  (gui '(+Radio) "group1" "value2b")
  ...
  (gui '(+Radio) "group2" "value2a")
  ...
  (gui '(+Radio) "group2" "value2b")
  ...

This way it should work as the only time when *Radio is important is
when a form is being built.

I imagine that if +Radio became part of picolisp code, setting *Radio
to NIL could happen inside the form function and people would not have
to worry about it.

>I think the right way to go would be to have '1st' be the "main"
>component of that radio group, where you can pass an offset like -1,
>-2 etc. in the 'T' method. Each +gui component has an 'id' property
>that can be used for such arithmetics (so you don't have to use
>(length (get *Top 'gui))).

1st is the "main" component of that radio group actually.  Except it
currently holds more information, like the whole thing returned by
(assoc Grp *Radio).

I did not know about the id property and I am not sure what does it
contain exactly.  If it contains the number which is rendered in html
in the name attribute as : name="*Gui(+)" then 1st could be
directly the first gui radio button in the group, its id property used
for html rendering and (length (get *Top 'gui)) could be dropped off
the *Radio assoc list.

> 2. Why do you distinguish in the 'show>' method between directly calling
>'', and a "hand-made" version?
>
>> (ifn (: 1st)
>>( "Var" (: xval) (not (able)))
>>(prin "> ...
>
>Is there some subtle difference?

It is very important, because all radio buttons in one group must have
the same 'name' attribute (otherwise a browser would not know they
belong to the same group).  I simply reuse the name attribute of the
first radio button in the group.  I have to render the radio input
element manually for all radio buttons except the first one because
 does not do the right thing there.

Cheers,

Tomas
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: gui +Radio

2008-08-22 Thread Alexander Burger
Hi Tomas,

though I did not find the time yet to try your +Radio component, I'd
like to touch on two points:

> ## to be the first for HTML rendering and return NIL value.  *Radio
> ## must be set to NIL before a form is rendered.
> 
> (default *Radio NIL)

1. (default .. NIL) has no effect, (off *Radio) might be more
   appropriate. But the actual problem I see is using a global variable.
   The difficult question is *when* to clear that variable, so that it
   works also when the page is reloaded (possibly with a different
   status and layout), when the browser back-button is pressed, or
   during JavsScript postings.

   I think the right way to go would be to have '1st' be the "main"
   component of that radio group, where you can pass an offset like -1,
   -2 etc. in the 'T' method. Each +gui component has an 'id' property
   that can be used for such arithmetics (so you don't have to use
   (length (get *Top 'gui))).

2. Why do you distinguish in the 'show>' method between directly calling
   '', and a "hand-made" version?

   > (ifn (: 1st)
   >( "Var" (: xval) (not (able)))
   >(prin " ...

   Is there some subtle difference?

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]


Re: Getl and maps behavior?

2008-08-22 Thread Alexander Burger
Hi Tomas,

> Alex, why does getl return a list of (property-value . property-name)
> and not a list of (property-name . property-value)?

There are some practical reasons for representing the elements of
property lists in such a way.

Most of all, a cell can be passed to functions that expect a variable
'var' argument, like 'set', 'inc', 'pop', and many more. This is also
the reason for the property functions 'prop' and '::'.

   : (put 'A 'counter 0)
   -> 0

   : (put 'A 'list (1 2 3 4))
   -> (1 2 3 4)

   : (with 'A (inc (:: counter)))
   -> 1

   : (pop (prop 'A 'list))   
   -> 1

   : (show 'A)
   A NIL
  list (2 3 4)
  counter 1
   -> A

Another reason is that a property list could be searched for a given
value with 'assoc'.

Cheers,
- Alex
-- 
UNSUBSCRIBE: mailto:[EMAIL PROTECTED]